i2000-11-22 Alexander Larsson <alexl@redhat.com>
authorAlexander Larsson <alexl@src.gnome.org>
Wed, 22 Nov 2000 10:07:34 +0000 (10:07 +0000)
committerAlexander Larsson <alexl@src.gnome.org>
Wed, 22 Nov 2000 10:07:34 +0000 (10:07 +0000)
        * gdk/gdktypes.h:
Add new type GdkSpan

* docs/reference/gdk/gdk-sections.txt,
docs/reference/gdk/tmpl/regions.sgml, gdk/gdkregion-generic.c,
gdk/gdkregion.h:
Implement and document gdk_region_spans_intersect_foreach.

* gdk/linux-fb/Makefile.am, gdk/linux-fb/gdkrender-fb.c:
Add new file gdkrender-fb.c which contains all core
rendering code.
Add gdk_fb_fill_rectangle_generic (old rectangle code) and
gdk_fb_fill_rectangle_simple_16, gdk_fb_fill_rectangle_simple_32
(optimized rectangle fillers).

* gdk/linux-fb/gdkdrawable-fb2.c:
Move all rendering code to gdkrender-fb.c.
Change from using GdkRectangles and GdkSegments for spans to GdkSpan.
Use the new span intersection functions in gdk_fb_fill_spans.
gdk_fb_draw_rectangle() clips filled rectangles and calls
gc->fill_rectangle with the result.
gdk_fb_fill_spans() gets extra argument "sorted".

* gdk/linux-fb/gdkevents-fb.c:
Remove unused includes and defines.
New function gdk_fb_get_time() to get correct time for events.

* gdk/linux-fb/gdkinput-ps2.c:
Use gdk method of generating multiple-clicks (gdk_event_button_generate)
Make sure to set the time of all events.

* gdk/linux-fb/gdkmain-fb.c:
Use gdk_fb_get_time ().

* gdk/linux-fb/gdkprivate-fb.h:
New virtual GC calls: fill_span & fill_rectangle.
Export gdk_fb_get_time().
gdk_fb_fill_spans() gets extra argument "sorted".

* gdk/linux-fb/mi*.c:
Use GdkSpan instead of GdkRectangle.
Pass correct sorted to gdk_fb_fill_spans. (sorted value taken
from XFree 4 source)

20 files changed:
docs/reference/gdk/gdk-sections.txt
docs/reference/gdk/tmpl/regions.sgml
gdk/gdkregion-generic.c
gdk/gdkregion.h
gdk/gdktypes.h
gdk/linux-fb/Makefile.am
gdk/linux-fb/gdkdrawable-fb2.c
gdk/linux-fb/gdkevents-fb.c
gdk/linux-fb/gdkinput-ps2.c
gdk/linux-fb/gdkmain-fb.c
gdk/linux-fb/gdkprivate-fb.h
gdk/linux-fb/gdkrender-fb.c [new file with mode: 0644]
gdk/linux-fb/miarc.c
gdk/linux-fb/mifillarc.c
gdk/linux-fb/mifpolycon.c
gdk/linux-fb/mipolygen.c
gdk/linux-fb/mispans.c
gdk/linux-fb/mispans.h
gdk/linux-fb/miwideline.c
gdk/linux-fb/mizerline.c

index f06b366805793fc788e77595760f8900c728339a..7cadb6277445fede2a19af04647bc79a08796a73 100644 (file)
@@ -620,6 +620,12 @@ gdk_region_intersect
 gdk_region_union
 gdk_region_subtract
 gdk_region_xor
+
+<SUBSECTION>
+GdkSpan
+GdkSpanFunc
+gdk_region_spans_intersect_foreach
+
 </SECTION>
 
 <SECTION>
index 9f92c8e13d36fb934126b456b73c9e3712fae42e..88e3e2d62ebaf0c94d4bfbfe85143ebe13b56b5b 100644 (file)
@@ -6,8 +6,8 @@ simple graphical data types.
 
 <!-- ##### SECTION Long_Description ##### -->
 <para>
-GDK provides the #GdkPoint, #GdkRectangle and #GdkRegion data types for
-representing pixels and sets of pixels on the screen.
+GDK provides the #GdkPoint, #GdkRectangle, #GdkRegion and #GdkSpan data types
+for representing pixels and sets of pixels on the screen.
 </para>
 <para>
 #GdkPoint is a simple structure containing an x and y coordinate of a point.
@@ -22,6 +22,11 @@ gdk_rectangle_union().
 #GdkRegion is an opaque data type holding a set of arbitrary pixels, and is
 usually used for clipping graphical operations (see gdk_gc_set_clip_region()).
 </para>
+<para>
+#GdkSpan is a structure holding a spanline. A spanline is a horizontal line that
+is one pixel wide. It is mainly used when rasterizing other graphics primitives.
+It can be intersected to regions by using gdk_region_spans_intersect_foreach().
+</para>
 
 <!-- ##### SECTION See_Also ##### -->
 <para>
@@ -261,3 +266,36 @@ Returns the union of a region and a rectangle.
 @source2: 
 
 
+<!-- ##### STRUCT GdkSpan ##### -->
+<para>
+
+</para>
+
+@x: 
+@y: 
+@width: 
+
+<!-- ##### USER_FUNCTION GdkSpanFunc ##### -->
+<para>
+
+</para>
+
+@span: The intersected part of the span.
+@data: Opaque data passed by user.
+
+
+<!-- ##### FUNCTION gdk_region_spans_intersect_foreach ##### -->
+<para>
+Intersects a set of spans with a region and call a user specified
+function for each resulting spanline. This function is a lot more effective
+if the spans are sorted.
+</para>
+
+@region: The region to intersect against.
+@spans: Array of spans to intersect.
+@n_spans: Number of spans.
+@sorted: True if the spans are sorted in increasing y order.
+@function: The function to call for each intersected spanline.
+@data: Opaque user data passed to function.
+
+
index 4c3e42ece7f4d02be529ffcefff1e07bb67a86f5..56e2bb370f437542913650afe345513599970237 100644 (file)
@@ -1505,3 +1505,153 @@ gdk_region_rect_in (GdkRegion    *region,
              GDK_OVERLAP_RECTANGLE_PART : GDK_OVERLAP_RECTANGLE_IN) : 
          GDK_OVERLAP_RECTANGLE_OUT);
 }
+
+
+static void
+gdk_region_unsorted_spans_intersect_foreach (GdkRegion *region,
+                                            GdkSpan   *spans,
+                                            int        n_spans,
+                                            GdkSpanFunc function,
+                                            gpointer data)
+{
+  gint i, left, right, y;
+  gint clipped_left, clipped_right;
+  GdkRegionBox *pbox;
+  GdkRegionBox *pboxEnd;
+  GdkSpan out_span;
+
+  if (!region->numRects)
+    return;
+
+  for (i=0;i<n_spans;i++)
+    {
+      y = spans[i].y;
+      left = spans[i].x;
+      right = left + spans[i].width; /* right is not in the span! */
+    
+      if (! ((region->extents.y1 <= y) &&
+            (region->extents.y2 > y) &&
+            (region->extents.x1 < right) &&
+            (region->extents.x2 > left)) ) 
+       continue;
+
+      /* can stop when we passed y */
+      for (pbox = region->rects, pboxEnd = pbox + region->numRects;
+          pbox < pboxEnd;
+          pbox++)
+       {
+         if (pbox->y2 <= y)
+           continue; /* Not quite there yet */
+         
+         if (pbox->y1 > y)
+           break; /* passed the spanline */
+         
+         if ((right > pbox->x1) && (left < pbox->x2)) 
+           {
+             clipped_left = MAX (left, pbox->x1);
+             clipped_right = MIN (right, pbox->x2);
+             
+             out_span.y = y;
+             out_span.x = clipped_left;
+             out_span.width = clipped_right - clipped_left;
+             (*function) (&out_span, data);
+           }
+       }
+    }
+}
+
+
+void
+gdk_region_spans_intersect_foreach (GdkRegion  *region,
+                                   GdkSpan    *spans,
+                                   int         n_spans,
+                                   gboolean    sorted,
+                                   GdkSpanFunc function,
+                                   gpointer    data)
+{
+  gint left, right, y;
+  gint clipped_left, clipped_right;
+  GdkRegionBox *pbox;
+  GdkRegionBox *pboxEnd;
+  GdkSpan *span, *tmpspan;
+  GdkSpan *end_span;
+  GdkSpan out_span;
+
+  if (!sorted)
+    {
+      gdk_region_unsorted_spans_intersect_foreach (region,
+                                                  spans,
+                                                  n_spans,
+                                                  function,
+                                                  data);
+      return;
+    }
+  
+  if ((!region->numRects) || (n_spans == 0))
+    return;
+
+  y = span->y;
+  left = span->x;
+  right = span->x + span->width; /* right is not in the span! */
+
+  /* The main method here is to step along the
+   * sorted rectangles and spans in lock step, and
+   * clipping the spans that are in the current
+   * rectangle before going on to the next rectangle.
+   */
+
+  span = spans;
+  end_span = spans + n_spans;
+  pbox = region->rects;
+  pboxEnd = pbox + region->numRects;
+  while (pbox < pboxEnd)
+    {
+      while ((pbox->y2 < span->y) || (span->y < pbox->y1))
+       {
+         /* Skip any rectangles that are above the current span */
+         if (pbox->y2 < span->y)
+           {
+             pbox++;
+             if (pbox == pboxEnd)
+               return;
+           }
+         /* Skip any spans that are above the current rectangle */
+         if (span->y < pbox->y1)
+           {
+             span++;
+             if (span == end_span)
+               return;
+           }
+       }
+      
+      /* Ok, we got at least one span that might intersect this rectangle. */
+      tmpspan = span;
+      while ((tmpspan < end_span) &&
+            (tmpspan->y < pbox->y2))
+       {
+         y = tmpspan->y;
+         left = tmpspan->x;
+         right = left + tmpspan->width; /* right is not in the span! */
+         
+         if ((right > pbox->x1) && (left < pbox->x2))
+           {
+             clipped_left = MAX (left, pbox->x1);
+             clipped_right = MIN (right, pbox->x2);
+             
+             out_span.y = y;
+             out_span.x = clipped_left;
+             out_span.width = clipped_right - clipped_left;
+             (*function) (&out_span, data);
+           }
+         
+         tmpspan++;
+       }
+
+      /* Finished this rectangle.
+       * The spans could still intersect the next one
+       */
+      pbox++;
+    }
+  
+  return spans;
+}
index 2551797a855c04066c2ae3266d1bdd2d7a080d16..ad20a65817d14a0af2ea22dc4a7b7b11dd619709 100644 (file)
@@ -29,6 +29,9 @@ typedef enum
   GDK_OVERLAP_RECTANGLE_PART
 } GdkOverlapType;
 
+typedef void (*GdkSpanFunc) (GdkSpan *span,
+                            gpointer data);
+
 GdkRegion *gdk_region_new       (void);
 GdkRegion *gdk_region_polygon   (GdkPoint     *points,
                                 gint          npoints,
@@ -66,8 +69,16 @@ void gdk_region_subtract        (GdkRegion    *source1,
 void gdk_region_xor             (GdkRegion    *source1,
                                 GdkRegion    *source2);
 
+void gdk_region_spans_intersect_foreach (GdkRegion   *region,
+                                        GdkSpan     *spans,
+                                        int          n_spans,
+                                        gboolean     sorted,
+                                        GdkSpanFunc  function,
+                                        gpointer     data);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 
 #endif /* __GDK_REGION_H__ */
+
index aeaccb98007f88bdcd8095ddb90eacb6ac773645..cedf86dc6204304b92690c3de46dcaf5058706b6 100644 (file)
@@ -67,6 +67,7 @@ extern "C" {
 typedef struct _GdkPoint             GdkPoint;
 typedef struct _GdkRectangle         GdkRectangle;
 typedef struct _GdkSegment           GdkSegment;
+typedef struct _GdkSpan                      GdkSpan;
 
 /*
  * Note that on some platforms the wchar_t type
@@ -184,6 +185,13 @@ struct _GdkSegment
   gint y2;
 };
 
+struct _GdkSpan
+{
+  gint x;
+  gint y;
+  gint width;
+};
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 5f93ad610ce689915d1c96ed2aa70d23a2423b3b..71aa0258e396e0f6f1e982df795664ba772ae195 100644 (file)
@@ -50,6 +50,7 @@ libgdk_linux_fb_la_SOURCES =    \
        gdkinputprivate.h       \
        gdkinput-ps2.c          \
        gdkevents-fb.c          \
+       gdkrender-fb.c          \
        mi.h                    \
        miarc.c                 \
        midash.c                \
index 986274c2e8d7b29213e46288189056debcb483f9..24da82c7fe892f8bb6e6c2d566b99bdf02f03277 100644 (file)
@@ -1,20 +1,13 @@
 #include "gdkprivate-fb.h"
 #include "mi.h"
-
-#include <freetype/ftglyph.h>
-
 #include <string.h>
 
+#include <freetype/ftglyph.h>
 
 #ifndef g_alloca
 #define g_alloca alloca
 #endif
 
-static GetPixelRet  gdk_fb_drawable_get_pixel (GdkDrawable      *drawable,
-                                              GdkGC            *gc,
-                                              int               x,
-                                              int               y,
-                                              GdkColor         *spot);
 void                gdk_fb_draw_rectangle     (GdkDrawable      *drawable,
                                               GdkGC            *gc,
                                               gint              filled,
@@ -82,10 +75,6 @@ static void         gdk_fb_draw_segments      (GdkDrawable      *drawable,
                                               GdkGC            *gc,
                                               GdkSegment       *segs,
                                               gint              nsegs);
-static void         gdk_fb_draw_lines         (GdkDrawable      *drawable,
-                                              GdkGC            *gc,
-                                              GdkPoint         *points,
-                                              gint              npoints);
 static GdkColormap* gdk_fb_get_colormap       (GdkDrawable      *drawable);
 static void         gdk_fb_set_colormap       (GdkDrawable      *drawable,
                                               GdkColormap      *colormap);
@@ -313,419 +302,59 @@ gdk_fb_clip_region (GdkDrawable *drawable,
   return real_clip_region;
 }
 
-static void
-gdk_fb_fill_span_general (GdkDrawable *drawable,
-                         GdkGC       *gc,
-                         GdkSegment  *cur,
-                         GdkColor    *color)
-{
-  int curx, cury;
-  GdkColor spot = *color;
-  GdkGCFBData *gc_private;
-  GdkDrawableFBData *private;
-
-  private = GDK_DRAWABLE_FBDATA (drawable);
-  gc_private = GDK_GC_FBDATA (gc);
-
-  g_assert (gc);
-
-  {
-    int clipxoff, clipyoff; /* Amounts to add to curx & cury to get x & y in clip mask */
-    int tsxoff, tsyoff;
-    GdkDrawable *cmask;
-    guchar *clipmem;
-    guint mask_rowstride;
-    GdkPixmap *ts = NULL;
-    GdkDrawableFBData *ts_private;
-    gboolean solid_stipple;
-    GdkFunction func = gc_private->values.function;
-    
-    cmask = gc_private->values.clip_mask;
-    clipxoff = clipyoff = tsxoff = tsyoff = 0;
-    mask_rowstride = 0;
-    solid_stipple = FALSE;
-    clipmem = NULL;
-    if (cmask)
-      {
-       GdkDrawableFBData *cmask_private;
-       
-       cmask_private = GDK_DRAWABLE_IMPL_FBDATA (cmask);
-       
-       clipmem = cmask_private->mem;
-       clipxoff = cmask_private->abs_x - gc_private->values.clip_x_origin - private->abs_x;
-       clipyoff = cmask_private->abs_y - gc_private->values.clip_y_origin - private->abs_y;
-       mask_rowstride = cmask_private->rowstride;
-      }
-    
-    if (gc_private->values.fill == GDK_TILED &&
-       gc_private->values.tile)
-      {
-       gint xstep, ystep;
-       gint relx, rely;
-       GdkFBDrawingContext *dc, dc_data;
-       dc = &dc_data;
-       
-       gdk_fb_drawing_context_init (dc, drawable, gc, FALSE, TRUE);
-       
-       ts = gc_private->values.tile;
-       ts_private = GDK_DRAWABLE_IMPL_FBDATA (ts);
-       for (cury = cur->y1; cury < cur->y2; cury += ystep)
-         {
-           int drawh;
-           
-           rely = cury - private->abs_y;
-           drawh = (rely + gc_private->values.ts_y_origin) % ts_private->height;
-           if (drawh < 0)
-             drawh += GDK_DRAWABLE_FBDATA (ts)->height;
-           
-           ystep = MIN (ts_private->height - drawh, cur->y2 - rely);
-           
-           for (curx = cur->x1; curx < cur->x2; curx += xstep)
-             {
-               int draww;
-               
-               relx = curx - private->abs_x;
-               
-               draww = (relx + gc_private->values.ts_x_origin) % ts_private->width;
-               if (draww < 0)
-                 draww += ts_private->width;
-               
-               xstep = MIN (ts_private->width - draww, cur->x2 - relx);
-               
-               gdk_fb_draw_drawable_3 (drawable, gc, GDK_DRAWABLE_IMPL (ts),
-                                       dc,
-                                       draww, drawh,
-                                       relx, rely,
-                                       xstep, ystep);
-             }
-         }
-       
-       gdk_fb_drawing_context_finalize (dc);
-       
-       return;
-      }
-    else if ((gc_private->values.fill == GDK_STIPPLED ||
-             gc_private->values.fill == GDK_OPAQUE_STIPPLED) &&
-            gc_private->values.stipple)
-      {
-       ts = gc_private->values.stipple;
-       tsxoff = GDK_DRAWABLE_FBDATA (ts)->abs_x - gc_private->values.ts_x_origin - private->abs_x;
-       tsyoff = GDK_DRAWABLE_FBDATA (ts)->abs_y - gc_private->values.ts_y_origin - private->abs_y;
-       solid_stipple = (gc_private->values.fill == GDK_OPAQUE_STIPPLED);
-      }
-    
-    for (cury = cur->y1; cury < cur->y2; cury++)
-      {
-       for (curx = cur->x1; curx < cur->x2; curx++)
-         {
-           int maskx = curx+clipxoff, masky = cury + clipyoff;
-           guchar foo;
-           
-           if (cmask)
-             {
-               foo = clipmem[masky*mask_rowstride + (maskx >> 3)];
-               
-               if (!(foo & (1 << (maskx % 8))))
-                 continue;
-             }
-           
-           if (func == GDK_INVERT)
-             {
-               (gc_private->get_color) (drawable, gc, curx, cury, &spot);
-               spot.pixel = ~spot.pixel;
-               spot.red = ~spot.red;
-               spot.green = ~spot.green;
-               spot.blue = ~spot.blue;
-             }
-           else if (ts)
-             {
-               int wid, hih;
-               
-               ts_private = GDK_DRAWABLE_IMPL_FBDATA (ts);
-               
-               wid = ts_private->width;
-               hih = ts_private->height;
-               
-               maskx = (curx+tsxoff)%wid;
-               masky = (cury+tsyoff)%hih;
-               if (maskx < 0)
-                 maskx += wid;
-               if (masky < 0)
-                 masky += hih;
-               
-               foo = ts_private->mem[(maskx >> 3) + ts_private->rowstride*masky];
-               if (foo & (1 << (maskx % 8)))
-                 {
-                   spot = gc_private->values.foreground;
-                 }
-               else if (solid_stipple)
-                 {
-                   spot = gc_private->values.background;
-                 }
-               else
-                 continue;
-             }
-           
-           (gc_private->set_pixel) (drawable, gc, curx, cury, spot.pixel);
-         }
-      }
-  }
-}
-
-static void
-gdk_fb_fill_span_simple_1 (GdkDrawable *drawable,
-                          GdkGC       *gc,
-                          GdkSegment  *cur,
-                          GdkColor    *color)
-{
-  int curx, cury;
-  GdkGCFBData *gc_private;
-  GdkDrawableFBData *private;
-  guchar *mem, *ptr;
-  guint rowstride;
-
-  private = GDK_DRAWABLE_FBDATA (drawable);
-  gc_private = GDK_GC_FBDATA (gc);
-
-  g_assert (gc);
-
-  g_assert (!gc_private->values.clip_mask &&
-           !gc_private->values.tile &&
-           !gc_private->values.stipple &&
-           gc_private->values.function != GDK_INVERT);
-
-  mem = private->mem;
-  rowstride = private->rowstride;
-
-  {
-    int fromx = MIN ((cur->x1+7)&(~7), cur->x2);
-    int begn = fromx - cur->x1, begoff = cur->x1 % 8, endn;
-    guchar begmask, endmask;
-    int body_end = cur->x2 & ~7;
-    int body_len = (body_end - fromx)/8;
-    
-    begmask = ((1 << (begn + begoff)) - 1)
-      & ~((1 << (begoff)) - 1);
-    endn = cur->x2 - body_end;
-    endmask = (1 << endn) - 1;
-    
-    for (cury = cur->y1; cury < cur->y2; cury++)
-      {
-       ptr = mem + cury*rowstride + (cur->x1 >> 3);
-       
-       if (color->pixel)
-         *ptr |= begmask;
-       else
-         *ptr &= ~begmask;
-       
-       curx = fromx;
-       
-       if (curx < cur->x2)
-         {
-           ptr = mem + cury*rowstride + (curx >> 3);
-           memset (ptr, color->pixel?0xFF:0, body_len);
-           
-           if (endn)
-             {
-               ptr = mem + cury*rowstride + (body_end >> 3);
-               if (color->pixel)
-                 *ptr |= endmask;
-               else
-                 *ptr &= ~endmask;
-             }
-         }
-      }
-  }
-}
 
-static void
-gdk_fb_fill_span_simple_8 (GdkDrawable *drawable,
-                          GdkGC       *gc,
-                          GdkSegment  *cur,
-                          GdkColor    *color)
+struct GdkSpanHelper
 {
-  int cury;
-  GdkGCFBData *gc_private;
-  GdkDrawableFBData *private;
-  guchar *mem, *ptr;
-  guint rowstride;
-
-  private = GDK_DRAWABLE_FBDATA (drawable);
-  gc_private = GDK_GC_FBDATA (gc);
-
-  g_assert (gc);
-
-  g_assert (!gc_private->values.clip_mask &&
-           !gc_private->values.tile &&
-           !gc_private->values.stipple &&
-           gc_private->values.function != GDK_INVERT);
-
-  mem = private->mem;
-  rowstride = private->rowstride;
-
-  for (cury = cur->y1; cury < cur->y2; cury++)
-    {
-      ptr = mem + cury*rowstride + cur->x1;
-      memset (ptr, color->pixel, cur->x2 - cur->x1);
-    }
-}
-static void
-gdk_fb_fill_span_simple_16 (GdkDrawable *drawable,
-                           GdkGC       *gc,
-                           GdkSegment  *cur,
-                           GdkColor    *color)
-{
-  int cury;
-  GdkGCFBData *gc_private;
-  GdkDrawableFBData *private;
-  guchar *mem;
-  guint rowstride;
-  int n;
-  int i;
-
-  private = GDK_DRAWABLE_FBDATA (drawable);
-  gc_private = GDK_GC_FBDATA (gc);
-
-  g_assert (gc);
-
-  g_assert (!gc_private->values.clip_mask &&
-           !gc_private->values.tile &&
-           !gc_private->values.stipple &&
-           gc_private->values.function != GDK_INVERT);
-
-  mem = private->mem;
-  rowstride = private->rowstride;
-
-  n = cur->x2 - cur->x1;
-  for (cury = cur->y1; cury < cur->y2; cury++)
-    {
-      guint16 *p16 = (guint16 *)(mem + cury * rowstride + cur->x1*2);
-      for (i = 0; i < n; i++)
-       *(p16++) = color->pixel;
-    }
-}
-
-static void
-gdk_fb_fill_span_simple_24 (GdkDrawable *drawable,
-                           GdkGC       *gc,
-                           GdkSegment  *cur,
-                           GdkColor    *color)
-{
-  int cury;
-  GdkGCFBData *gc_private;
-  GdkDrawableFBData *private;
-  guchar *mem, *ptr;
-  guint rowstride;
-  int n;
-  guchar redval, greenval, blueval;
-  guchar *firstline, *ptr_end;
-
-  private = GDK_DRAWABLE_FBDATA (drawable);
-  gc_private = GDK_GC_FBDATA (gc);
-
-  g_assert (gc);
-
-  g_assert (!gc_private->values.clip_mask &&
-           !gc_private->values.tile &&
-           !gc_private->values.stipple &&
-           gc_private->values.function != GDK_INVERT);
-
-  mem = private->mem;
-  rowstride = private->rowstride;
+  GdkDrawable *drawable;
+  GdkGC *gc;
+  GdkColor color;
+};
 
-  {
-    redval = color->red>>8;
-    greenval = color->green>>8;
-    blueval = color->blue>>8;
-    
-    if ((cur->y2 - cur->y1) <= 0)
-      return;
-    
-    n = (cur->x2 - cur->x1)*3;
-    
-    firstline = ptr = mem + cur->y1 * rowstride + cur->x1*3;
-    ptr_end = ptr+n;
-    while (ptr < ptr_end)
-      {
-       ptr[gdk_display->red_byte] = redval;
-       ptr[gdk_display->green_byte] = greenval;
-       ptr[gdk_display->blue_byte] = blueval;
-       ptr += 3;
-      }
-    for (cury = cur->y1 + 1, ptr = mem + cury * rowstride + cur->x1*3; cury < cur->y2; cury++, ptr += rowstride)
-      {
-       memcpy (ptr, firstline, n);
-      }
-  }
-}
 static void
-gdk_fb_fill_span_simple_32 (GdkDrawable *drawable,
-                           GdkGC       *gc,
-                           GdkSegment  *cur,
-                           GdkColor    *color)
+gdk_fb_fill_span_helper(GdkSpan *span,
+                       gpointer data)
 {
-  int cury;
-  GdkGCFBData *gc_private;
-  GdkDrawableFBData *private;
-  guchar *mem;
-  guint rowstride;
-  int n;
-  int i;
-
-  private = GDK_DRAWABLE_FBDATA (drawable);
-  gc_private = GDK_GC_FBDATA (gc);
-
-  g_assert (gc);
-
-  g_assert (!gc_private->values.clip_mask &&
-           !gc_private->values.tile &&
-           !gc_private->values.stipple &&
-           gc_private->values.function != GDK_INVERT);
-
-  mem = private->mem;
-  rowstride = private->rowstride;
-
-  n = cur->x2 - cur->x1;
-  for (cury = cur->y1; cury < cur->y2; cury++)
-    {
-      guint32 *p32 = (guint32 *)(mem + cury * rowstride + cur->x1*4);
-      for (i = 0; i < n; i++)
-       *(p32++) = color->pixel;
-    }
+  struct GdkSpanHelper *info = (struct GdkSpanHelper *)data;
+  GdkGC * gc = info->gc;
+  
+  (GDK_GC_FBDATA (gc)->fill_span) (info->drawable, gc, span, &info->color);
 }
 
-
-
 void
 gdk_fb_fill_spans (GdkDrawable *real_drawable,
                   GdkGC *gc,
-                  GdkRectangle *rects,
-                  int nrects)
+                  GdkSpan *spans,
+                  int nspans,
+                  gboolean sorted)
 {
   int i;
-  GdkColor color;
-  GdkRegion *real_clip_region, *tmpreg;
-  GdkRectangle draw_rect;
+  struct GdkSpanHelper info;
+  GdkRegion *real_clip_region;
   gboolean handle_cursor = FALSE;
   GdkDrawable *drawable;
   GdkDrawableFBData *private;
-
+  
   drawable = real_drawable;
   private = GDK_DRAWABLE_FBDATA (drawable);
 
+  g_assert (gc);
+
   if (GDK_IS_WINDOW (private->wrapper) && !GDK_WINDOW_P (private->wrapper)->mapped)
     return;
   if (GDK_IS_WINDOW (private->wrapper) && GDK_WINDOW_P (private->wrapper)->input_only)
     g_error ("Drawing on the evil input-only!");
 
-  if (gc && (GDK_GC_FBDATA (gc)->values_mask & GDK_GC_FOREGROUND))
-    color = GDK_GC_FBDATA (gc)->values.foreground;
+  info.drawable = drawable;
+  info.gc = gc;
+  
+  if (GDK_GC_FBDATA (gc)->values_mask & GDK_GC_FOREGROUND)
+    info.color = GDK_GC_FBDATA (gc)->values.foreground;
   else if (GDK_IS_WINDOW (private->wrapper))
-    color = GDK_WINDOW_P (private->wrapper)->bg_color;
+    info.color = GDK_WINDOW_P (private->wrapper)->bg_color;
   else
-    gdk_color_black (private->colormap, &color);
+    gdk_color_black (private->colormap, &info.color);
 
-  real_clip_region = gdk_fb_clip_region (drawable, gc, TRUE, (!gc || GDK_GC_FBDATA (gc)->values.function != GDK_INVERT));
+  real_clip_region = gdk_fb_clip_region (drawable, gc, TRUE, GDK_GC_FBDATA (gc)->values.function != GDK_INVERT);
 
   if (private->mem == GDK_DRAWABLE_IMPL_FBDATA (gdk_parent_root)->mem &&
       gdk_fb_cursor_region_need_hide (real_clip_region))
@@ -733,364 +362,46 @@ gdk_fb_fill_spans (GdkDrawable *real_drawable,
       handle_cursor = TRUE;
       gdk_fb_cursor_hide ();
     }
-    
-  for (i = 0; i < nrects; i++)
-    {
-      GdkSegment cur;
-      int j;
-
-      cur.x1 = rects[i].x;
-      cur.y1 = rects[i].y;
-      cur.x2 = cur.x1 + rects[i].width;
-      cur.y2 = cur.y1 + rects[i].height;
-      g_assert (cur.x2 >= cur.x1);
-      g_assert (cur.y2 >= cur.y1);
-
-      cur.x1 += private->abs_x;
-      cur.x1 = MAX (cur.x1, private->llim_x);
-
-      cur.x2 += private->abs_x;
-      cur.x2 = MIN (cur.x2, private->lim_x);
-      cur.x1 = MIN (cur.x1, cur.x2);
-
-      cur.y1 += private->abs_y;
-      cur.y1 = MAX (cur.y1, private->llim_y);
-
-      cur.y2 += private->abs_y;
-      cur.y2 = MIN (cur.y2, private->lim_y);
-      cur.y1 = MIN (cur.y1, cur.y2);
 
-      draw_rect.x = cur.x1;
-      draw_rect.y = cur.y1;
-      draw_rect.width = cur.x2 - cur.x1;
-      draw_rect.height = cur.y2 - cur.y1;
+  for (i = 0; i < nspans; i++)
+    {
+      GdkSpan *cur;
+      
+      cur = &spans[i];
+      
+      cur->x += private->abs_x;
+      cur->y += private->abs_y;
 
-      switch (gdk_region_rect_in (real_clip_region, &draw_rect))
+      if ( (cur->y < private->llim_y) || (cur->y >= private->lim_y))
+       cur->width = 0;
+      
+      if (cur->x < private->llim_x)
        {
-       case GDK_OVERLAP_RECTANGLE_PART:
-         tmpreg = gdk_region_rectangle (&draw_rect);
-         gdk_region_intersect (tmpreg, real_clip_region);
-         for (j = 0; j < tmpreg->numRects; j++)
-           {
-             cur = tmpreg->rects[j];
-             (GDK_GC_FBDATA (gc)->fill_span) (drawable, gc, &cur, &color);
-           }
-         gdk_region_destroy (tmpreg);
-         break;
-       case GDK_OVERLAP_RECTANGLE_IN:
-         (GDK_GC_FBDATA (gc)->fill_span) (drawable, gc, &cur, &color);
-         break;
-       default:
-         break;
+         cur->width -= private->llim_x - cur->x;
+         cur->x = private->llim_x;
+       }
+      
+      if (cur->x + cur->width > private->lim_x)
+       {
+         cur->width = private->lim_x - cur->x;
        }
+
+      if (cur->width <= 0)
+       cur->width = 0;
     }
 
+  gdk_region_spans_intersect_foreach (real_clip_region,
+                                     spans,
+                                     nspans,
+                                     sorted,
+                                     gdk_fb_fill_span_helper,
+                                     &info);
+
   gdk_region_destroy (real_clip_region);
   if (handle_cursor)
     gdk_fb_cursor_unhide ();
 }
 
-static GetPixelRet
-gdk_fb_drawable_get_pixel (GdkDrawable *drawable,
-                          GdkGC *gc,
-                          int x,
-                          int y,
-                          GdkColor *spot)
-{
-  GetPixelRet retval = GPR_NONE;
-  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
-  guchar *mem = private->mem;
-  guint rowstride = private->rowstride;
-
-  switch (private->depth)
-    {
-    case 1:
-      {
-       guchar foo = mem[(x >> 3) + y * rowstride];
-       if (foo & (1 << (x % 8)))
-         *spot = GDK_GC_FBDATA (gc)->values.foreground;
-       else
-         {
-           retval = GPR_USED_BG;
-           *spot = GDK_GC_FBDATA (gc)->values.background;
-         }
-      }
-      break;
-    case 71:
-      if (mem[x + y * rowstride])
-       *spot = GDK_GC_FBDATA (gc)->values.foreground;
-      else
-       *spot = GDK_GC_FBDATA (gc)->values.background;
-      break;
-    case 77:
-      retval = GPR_AA_GRAYVAL;
-      spot->pixel = mem[x + y * rowstride] << 1;
-      spot->red = spot->green = spot->blue = spot->pixel << 8;
-      break;
-    case 78: /* AA mode */
-      retval = GPR_AA_GRAYVAL;
-      spot->pixel = mem[x + y * rowstride];
-      spot->red = spot->green = spot->blue = spot->pixel << 8;
-      break;
-    case 8:
-      spot->pixel = mem[x + y * rowstride];
-      *spot = private->colormap->colors[spot->pixel];
-      break;
-    case 16:
-      {
-       guint16 val16 = *((guint16 *)&mem[x*2 + y*rowstride]);
-
-       spot->red = (((1<<gdk_display->modeinfo.red.length) - 1) & (val16 >> gdk_display->modeinfo.red.offset)) << (16 - gdk_display->modeinfo.red.length);
-       spot->green = (((1<<gdk_display->modeinfo.green.length) - 1) & (val16 >> gdk_display->modeinfo.green.offset)) << (16 - gdk_display->modeinfo.green.length);
-       spot->blue = (((1<<gdk_display->modeinfo.blue.length) - 1) & (val16 >> gdk_display->modeinfo.blue.offset)) << (16 - gdk_display->modeinfo.blue.length);
-
-       spot->pixel = val16;
-      }
-      break;
-    case 24:
-      {
-       guchar *smem = &mem[x*3 + y*rowstride];
-       spot->red = smem[gdk_display->red_byte] << 8;
-       spot->green = smem[gdk_display->green_byte] << 8;
-       spot->blue = smem[gdk_display->blue_byte] << 8;
-#if (G_BYTE_ORDER == G_BIG_ENDIAN)
-       spot->pixel = (smem[0]<<16)|(smem[1]<<8)|smem[2];
-#else
-       spot->pixel = smem[0]|(smem[1]<<8)|(smem[2]<<16);
-#endif
-      }
-      break;
-    case 32:
-      {
-       guchar *smem = &mem[x*4 + y*rowstride];
-       spot->red = smem[gdk_display->red_byte] << 8;
-       spot->green = smem[gdk_display->green_byte] << 8;
-       spot->blue = smem[gdk_display->blue_byte] << 8;
-       spot->pixel = *(guint32 *)smem;
-      }
-      break;
-    }
-
-  return retval;
-}
-
-static void
-gdk_fb_drawable_set_pixel_1(GdkDrawable *drawable,
-                           GdkGC *gc,
-                           int x,
-                           int y,
-                           gulong pixel)
-{
-  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
-  guchar *mem = private->mem;
-  guint rowstride = private->rowstride;
-  guchar *ptr;
-
-  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
-  
-  ptr = mem + (y*rowstride) + (x >> 3);
-
-  if (pixel)
-    *ptr |= (1 << (x % 8));
-  else
-    *ptr &= ~(1 << (x % 8));
-}
-
-static void
-gdk_fb_drawable_set_pixel_8(GdkDrawable *drawable,
-                           GdkGC *gc,
-                           int x,
-                           int y,
-                           gulong pixel)
-{
-  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
-  guchar *mem = private->mem;
-  guint rowstride = private->rowstride;
-
-  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
-
-  mem[x + y*rowstride] = pixel;
-}
-
-static void
-gdk_fb_drawable_set_pixel_16(GdkDrawable *drawable,
-                            GdkGC *gc,
-                            int x,
-                            int y,
-                            gulong pixel)
-{
-  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
-  guchar *mem = private->mem;
-  guint rowstride = private->rowstride;
-  guint16 *ptr;
-
-  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
-  
-  ptr = (guint16 *)&mem[x*2 + y*rowstride];
-  *ptr = pixel;
-}
-
-static void
-gdk_fb_drawable_set_pixel_24(GdkDrawable *drawable,
-                           GdkGC *gc,
-                           int x,
-                           int y,
-                           gulong pixel)
-{
-  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
-  guchar *mem = private->mem;
-  guint rowstride = private->rowstride;
-  guchar *smem;
-  
-  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
-  
-  smem = &mem[x*3 + y*rowstride];
-  smem[0] = pixel & 0xff;
-  smem[1] = (pixel >> 8) & 0xff;
-  smem[2] = (pixel >> 16) & 0xff;
-}
-
-static void
-gdk_fb_drawable_set_pixel_32(GdkDrawable *drawable,
-                           GdkGC *gc,
-                           int x,
-                           int y,
-                           gulong pixel)
-{
-  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
-  guchar *mem = private->mem;
-  guint rowstride = private->rowstride;
-  guint32 *smem;
-
-  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
-  
-  smem = (guint32 *)&mem[x*4 + y*rowstride];
-  *smem = pixel;
-}
-
-
-static GetPixelRet
-gdk_fb_drawable_get_color_1 (GdkDrawable *drawable,
-                            GdkGC *gc,
-                            int x,
-                            int y,
-                            GdkColor *color)
-{
-  GetPixelRet retval = GPR_NONE;
-  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
-  guchar *mem = private->mem;
-  guint rowstride = private->rowstride;
-  guchar foo;
-
-  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
-  
-  foo = mem[(x >> 3) + y * rowstride];
-  if (foo & (1 << (x % 8)))
-    *color = GDK_GC_FBDATA (gc)->values.foreground;
-  else
-    {
-      retval = GPR_USED_BG;
-
-      *color = GDK_GC_FBDATA (gc)->values.background;
-    }
-  
-  return retval;
-}
-
-static GetPixelRet
-gdk_fb_drawable_get_color_8 (GdkDrawable *drawable,
-                            GdkGC *gc,
-                            int x,
-                            int y,
-                            GdkColor *color)
-{
-  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
-  guchar *mem = private->mem;
-  guint rowstride = private->rowstride;
-  gint pixel;
-
-  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
-  
-  pixel = mem[x + y * rowstride];
-  *color = private->colormap->colors[pixel];
-
-  return GPR_NONE;
-}
-static GetPixelRet
-gdk_fb_drawable_get_color_16 (GdkDrawable *drawable,
-                             GdkGC *gc,
-                             int x,
-                             int y,
-                             GdkColor *color)
-{
-  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
-  guchar *mem = private->mem;
-  guint rowstride = private->rowstride;
-  guint16 val16;
-
-  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
-
-  val16 = *((guint16 *)&mem[x*2 + y*rowstride]);
-
-  color->red = (((1<<gdk_display->modeinfo.red.length) - 1) & (val16 >> gdk_display->modeinfo.red.offset)) << (16 - gdk_display->modeinfo.red.length);
-  color->green = (((1<<gdk_display->modeinfo.green.length) - 1) & (val16 >> gdk_display->modeinfo.green.offset)) << (16 - gdk_display->modeinfo.green.length);
-  color->blue = (((1<<gdk_display->modeinfo.blue.length) - 1) & (val16 >> gdk_display->modeinfo.blue.offset)) << (16 - gdk_display->modeinfo.blue.length);
-
-  color->pixel = val16;
-
-  return GPR_NONE;
-}
-
-static GetPixelRet
-gdk_fb_drawable_get_color_24 (GdkDrawable *drawable,
-                             GdkGC *gc,
-                             int x,
-                             int y,
-                             GdkColor *color)
-{
-  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
-  guchar *mem = private->mem;
-  guint rowstride = private->rowstride;
-  guchar *smem;
-
-  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
-
-  smem = &mem[x*3 + y*rowstride];
-  color->red = smem[gdk_display->red_byte] << 8;
-  color->green = smem[gdk_display->green_byte] << 8;
-  color->blue = smem[gdk_display->blue_byte] << 8;
-#if (G_BYTE_ORDER == G_BIG_ENDIAN)
-  color->pixel = (smem[0]<<16)|(smem[1]<<8)|smem[2];
-#else
-  color->pixel = smem[0]|(smem[1]<<8)|(smem[2]<<16);
-#endif
-
-  return GPR_NONE;
-}
-
-static GetPixelRet
-gdk_fb_drawable_get_color_32 (GdkDrawable *drawable,
-                             GdkGC *gc,
-                             int x,
-                             int y,
-                             GdkColor *color)
-{
-  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
-  guchar *mem = private->mem;
-  guint rowstride = private->rowstride;
-  guchar *smem;
-
-  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
-  
-  smem = &mem[x*4 + y*rowstride];
-  color->red = smem[gdk_display->red_byte] << 8;
-  color->green = smem[gdk_display->green_byte] << 8;
-  color->blue = smem[gdk_display->blue_byte] << 8;
-  color->pixel = *(guint32 *)smem;
-
-  return GPR_NONE;
-}
-
 void
 gdk_fb_drawing_context_init (GdkFBDrawingContext *dc,
                             GdkDrawable *drawable,
@@ -1153,183 +464,6 @@ gdk_fb_drawing_context_finalize (GdkFBDrawingContext *dc)
     gdk_fb_cursor_unhide ();
 }
 
-void
-gdk_fb_draw_drawable_memmove (GdkDrawable *drawable,
-                             GdkGC       *gc,
-                             GdkPixmap   *src,
-                             GdkFBDrawingContext *dc,
-                             gint         start_y,
-                             gint         end_y,
-                             gint         start_x,
-                             gint         end_x,
-                             gint         src_x_off,
-                             gint         src_y_off,
-                             gint         draw_direction)
-{
-  GdkDrawableFBData *src_private = GDK_DRAWABLE_FBDATA (src);
-  guint depth = src_private->depth;
-  guint src_rowstride = src_private->rowstride;
-  guchar *srcmem = src_private->mem;
-  int linelen = (end_x - start_x)*(depth>>3);
-  gint cur_y;
-  
-  for(cur_y = start_y; cur_y*draw_direction < end_y*draw_direction; cur_y += draw_direction)
-    {
-      memmove (dc->mem + (cur_y * dc->rowstride) + start_x*(depth>>3),
-              srcmem + ((cur_y + src_y_off)*src_rowstride) + (start_x + src_x_off)*(depth>>3),
-              linelen);
-    }
-
-}
-
-
-void
-gdk_fb_draw_drawable_generic (GdkDrawable *drawable,
-                             GdkGC       *gc,
-                             GdkPixmap   *src,
-                             GdkFBDrawingContext *dc,
-                             gint         start_y,
-                             gint         end_y,
-                             gint         start_x,
-                             gint         end_x,
-                             gint         src_x_off,
-                             gint         src_y_off,
-                             gint         draw_direction)
-{
-  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
-  int cur_x, cur_y;
-
-  for (cur_y = start_y; cur_y*draw_direction < end_y*draw_direction; cur_y+=draw_direction)
-    {
-      for (cur_x = start_x; cur_x < end_x; cur_x++)
-       {
-         GdkColor spot;
-         
-         if (GDK_GC_FBDATA(gc)->values.clip_mask)
-           {
-             int maskx = cur_x + dc->clipxoff, masky = cur_y + dc->clipyoff;
-             guchar foo;
-             
-             foo = dc->clipmem[masky*dc->clip_rowstride + (maskx >> 3)];
-             
-             if (!(foo & (1 << (maskx % 8))))
-               continue;
-           }
-         
-         switch (gdk_fb_drawable_get_pixel (src, gc, cur_x + src_x_off, cur_y + src_y_off, &spot))
-           {
-           case GPR_AA_GRAYVAL:
-             {
-               GdkColor realspot, fg;
-               guint graylevel = spot.pixel;
-               gint tmp;
-               
-               if (private->depth == 1)
-                 {
-                   if (spot.pixel > 192)
-                     spot = GDK_GC_FBDATA (gc)->values.foreground;
-                   else
-                     spot = GDK_GC_FBDATA (gc)->values.background;
-                   break;
-                 }
-               else
-                 {
-                   if (graylevel >= 254)
-                     {
-                       spot = GDK_GC_FBDATA (gc)->values.foreground;
-                     }
-                   else if (graylevel <= 2)
-                     {
-                       if (!dc->draw_bg)
-                         continue;
-                       
-                       spot = GDK_GC_FBDATA (gc)->values.background;
-                     }
-                   else
-                     {
-                       switch ((GDK_GC_FBDATA (gc)->get_color) (drawable, gc, cur_x, cur_y, &realspot))
-                         {
-                         case GPR_USED_BG:
-                           {
-                             int bgx, bgy;
-                             
-                             bgx = (cur_x - GDK_DRAWABLE_IMPL_FBDATA (dc->bg_relto)->abs_x) % GDK_DRAWABLE_IMPL_FBDATA (dc->bgpm)->width + private->abs_x;
-                             bgy = (cur_y - GDK_DRAWABLE_IMPL_FBDATA (dc->bg_relto)->abs_y) % GDK_DRAWABLE_IMPL_FBDATA (dc->bgpm)->height + private->abs_y;
-                             gdk_fb_drawable_get_pixel (dc->bgpm, gc, bgx, bgy, &realspot);
-                           }
-                           break;
-                         case GPR_NONE:
-                           break;
-                         default:
-                           g_assert_not_reached ();
-                           break;
-                         }
-                       
-                       fg = GDK_GC_FBDATA (gc)->values.foreground;
-
-                       /* Now figure out what 'spot' should actually look like */
-                       fg.red >>= 8;
-                       fg.green >>= 8;
-                       fg.blue >>= 8;
-                       realspot.red >>= 8;
-                       realspot.green >>= 8;
-                       realspot.blue >>= 8;
-
-                               
-                       tmp = (fg.red - realspot.red) * graylevel;
-                       spot.red = realspot.red + ((tmp + (tmp >> 8) + 0x80) >> 8);
-                       spot.red <<= 8;
-                       
-                       tmp = (fg.green - realspot.green) * graylevel;
-                       spot.green = realspot.green + ((tmp + (tmp >> 8) + 0x80) >> 8);
-                       spot.green <<= 8;
-                       
-                       tmp = (fg.blue - realspot.blue) * graylevel;
-                       spot.blue = realspot.blue + ((tmp + (tmp >> 8) + 0x80) >> 8);
-                       spot.blue <<= 8;
-                       
-                       /* Now find the pixel for this thingie */
-                       switch (private->depth)
-                         {
-                         case 8:
-                           if (!gdk_colormap_alloc_color (private->colormap, &spot, FALSE, TRUE))
-                             {
-                               g_error ("Can't allocate AA color!");
-                             }
-                           break;
-                         case 16:
-                           spot.pixel = (spot.red >> (16 - gdk_display->modeinfo.red.length)) << gdk_display->modeinfo.red.offset;
-                           spot.pixel |= (spot.green >> (16 - gdk_display->modeinfo.green.length)) << gdk_display->modeinfo.green.offset;
-                           spot.pixel |= (spot.blue >> (16 - gdk_display->modeinfo.blue.length)) << gdk_display->modeinfo.blue.offset;
-                           break;
-                         case 24:
-                         case 32:
-                           spot.pixel = ((spot.red & 0xFF00) >> 8  << (gdk_display->modeinfo.red.offset))
-                             | ((spot.green & 0xFF00) >> 8 << (gdk_display->modeinfo.green.offset))
-                             | ((spot.blue & 0xFF00) >> 8 << (gdk_display->modeinfo.blue.offset));
-                           break;
-                         }
-                     }
-                 }
-             }
-             break;
-           case GPR_USED_BG:
-             if (!dc->draw_bg)
-               continue;
-             break;
-           case GPR_NONE:
-             break;
-           default:
-             g_assert_not_reached ();
-             break;
-           }
-         
-         (GDK_GC_FBDATA (gc)->set_pixel) (drawable, gc, cur_x, cur_y, spot.pixel);
-       }
-    }
-
-}
-
 void
 gdk_fb_draw_drawable_2 (GdkDrawable *drawable,
                        GdkGC       *gc,
@@ -1505,178 +639,6 @@ gdk_fb_draw_drawable (GdkDrawable *drawable,
 }
 
 
-static void
-gdk_fb_draw_drawable_aa_24 (GdkDrawable *drawable,
-                           GdkGC       *gc,
-                           GdkPixmap   *src,
-                           GdkFBDrawingContext *dc,
-                           gint         start_y,
-                           gint         end_y,
-                           gint         start_x,
-                           gint         end_x,
-                           gint         src_x_off,
-                           gint         src_y_off,
-                           gint         draw_direction)
-{
-  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
-  int x, y;
-  GdkGCFBData *gc_private;
-  guchar *dmem = private->mem;
-  guint dst_rowstride = private->rowstride;
-  guchar *smem = GDK_DRAWABLE_FBDATA (src)->mem;
-  guint src_rowstride = GDK_DRAWABLE_FBDATA (src)->rowstride;
-  guchar *dst;
-  guint grayval;
-  gint r, g, b, tmp;
-  GdkColor fg;
-  gint fg_r, fg_g, fg_b;
-  
-  gc_private = GDK_GC_FBDATA (gc);
-
-  fg = GDK_GC_FBDATA (gc)->values.foreground;
-  fg_r = fg.red >> 8;
-  fg_g = fg.green >> 8;
-  fg_b = fg.blue >> 8;
-  
-  for (y = start_y; y*draw_direction < end_y*draw_direction; y+=draw_direction)
-    {
-      for (x = start_x; x < end_x; x++)
-       {
-         grayval = smem[x + src_x_off + (y + src_y_off) * src_rowstride];
-
-         if ((grayval <= 2) && (!dc->draw_bg))
-           continue;
-
-         dst = &dmem[x*3 + y*dst_rowstride];
-         
-         if (grayval >= 254)
-           {
-             dst[gdk_display->red_byte] = fg_r;
-             dst[gdk_display->green_byte] = fg_g;
-             dst[gdk_display->blue_byte] = fg_b;
-           }
-         else if (grayval <= 2)
-           {
-             dst[gdk_display->red_byte] = GDK_GC_FBDATA (gc)->values.background.red >> 8;
-             dst[gdk_display->green_byte] = GDK_GC_FBDATA (gc)->values.background.green >> 8;
-             dst[gdk_display->blue_byte] = GDK_GC_FBDATA (gc)->values.background.blue >> 8;
-           }
-         else
-           {
-             r = dst[gdk_display->red_byte];
-             tmp = (fg_r - r) * (gint)grayval;
-             r = r + ((tmp + (tmp >> 8) + 0x80) >> 8);
-             dst[gdk_display->red_byte] = r;
-
-             g = dst[gdk_display->green_byte];
-             tmp = (fg_g - g) * (gint)grayval;
-             g = g + ((tmp + (tmp >> 8) + 0x80) >> 8);
-             dst[gdk_display->green_byte] = g;
-
-             b = dst[gdk_display->blue_byte];
-             tmp = (fg_b - b) * (gint)grayval;
-             b = b + ((tmp + (tmp >> 8) + 0x80) >> 8);
-             dst[gdk_display->blue_byte] = b;
-           }
-       }
-    }
-}
-
-
-void
-_gdk_fb_gc_calc_state (GdkGC           *gc,
-                      GdkGCValuesMask  changed)
-{
-  GdkGCFBData *gc_private;
-  int i;
-
-  gc_private = GDK_GC_FBDATA (gc);
-
-  gc_private->fill_span = gdk_fb_fill_span_general;
-
-  for (i=0;i<GDK_NUM_FB_SRCBPP;i++)
-    gc_private->draw_drawable[i] = gdk_fb_draw_drawable_generic;
-  
-  if (changed & _GDK_FB_GC_DEPTH)
-    switch (gc_private->depth)
-      {
-      case 1:
-       gc_private->set_pixel = gdk_fb_drawable_set_pixel_1;
-       gc_private->get_color = gdk_fb_drawable_get_color_1;
-       break;
-      case 8:
-       gc_private->set_pixel = gdk_fb_drawable_set_pixel_8;
-       gc_private->get_color = gdk_fb_drawable_get_color_8;
-       break;
-      case 16:
-       gc_private->set_pixel = gdk_fb_drawable_set_pixel_16;
-       gc_private->get_color = gdk_fb_drawable_get_color_16;
-       break;
-      case 24:
-       gc_private->set_pixel = gdk_fb_drawable_set_pixel_24;
-       gc_private->get_color = gdk_fb_drawable_get_color_24;
-       break;
-      case 32:
-       gc_private->set_pixel = gdk_fb_drawable_set_pixel_32;
-       gc_private->get_color = gdk_fb_drawable_get_color_32;
-       break;
-      default:
-       g_assert_not_reached ();
-       break;
-      }
-
-  if (!gc_private->values.clip_mask)
-    {
-    switch (gc_private->depth)
-      {
-      case 8:
-       gc_private->draw_drawable[GDK_FB_SRC_BPP_8] = gdk_fb_draw_drawable_memmove;
-       break;
-      case 16:
-       gc_private->draw_drawable[GDK_FB_SRC_BPP_16] = gdk_fb_draw_drawable_memmove;
-       break;
-      case 24:
-       if (getenv("foo") && strcmp(getenv("foo"), "bar")==0)
-         gc_private->draw_drawable[GDK_FB_SRC_BPP_8_AA_GRAYVAL] = gdk_fb_draw_drawable_aa_24;
-       gc_private->draw_drawable[GDK_FB_SRC_BPP_24] = gdk_fb_draw_drawable_memmove;
-       break;
-      case 32:
-       gc_private->draw_drawable[GDK_FB_SRC_BPP_32] = gdk_fb_draw_drawable_memmove;
-       break;
-      }
-      
-    }
-
-  
-  if (!gc_private->values.clip_mask &&
-      !gc_private->values.tile &&
-      !gc_private->values.stipple &&
-       gc_private->values.function != GDK_INVERT)
-    {
-      switch (gc_private->depth)
-       {
-       case 1:
-         gc_private->fill_span = gdk_fb_fill_span_simple_1;
-         break;
-       case 8:
-         gc_private->fill_span = gdk_fb_fill_span_simple_8;
-         break;
-       case 16:
-         gc_private->fill_span = gdk_fb_fill_span_simple_16;
-         break;
-       case 24:
-         gc_private->fill_span = gdk_fb_fill_span_simple_24;
-         break;
-       case 32:
-         gc_private->fill_span = gdk_fb_fill_span_simple_32;
-         break;
-       default:
-         g_assert_not_reached ();
-         break;
-    }
-    }
-
-}
 
 
 static void
@@ -1712,19 +674,84 @@ gdk_fb_draw_rectangle (GdkDrawable    *drawable,
                       gint            width,
                       gint            height)
 {
-  GdkRectangle rect;
-
+  GdkDrawableFBData *private;
+  
+  private = GDK_DRAWABLE_FBDATA (drawable);
+  
   if (filled)
     {
-      rect.x = x;
-      rect.y = y;
-      rect.width = width;
-      rect.height = height;
-      gdk_fb_fill_spans (drawable, gc, &rect, 1);
+      gboolean handle_cursor = FALSE;
+      GdkRectangle tmprect;
+      GdkRegion *tmpreg;
+      GdkRegion *real_clip_region;
+      GdkColor color;
+      int i;
+      
+      if (GDK_GC_FBDATA (gc)->values_mask & GDK_GC_FOREGROUND)
+       color = GDK_GC_FBDATA (gc)->values.foreground;
+      else if (GDK_IS_WINDOW (private->wrapper))
+       color = GDK_WINDOW_P (private->wrapper)->bg_color;
+      else
+       gdk_color_black (private->colormap, &color);
+      
+      real_clip_region = gdk_fb_clip_region (drawable, gc, TRUE, GDK_GC_FBDATA (gc)->values.function != GDK_INVERT);
+      
+      if (private->mem == GDK_DRAWABLE_IMPL_FBDATA (gdk_parent_root)->mem &&
+         gdk_fb_cursor_region_need_hide (real_clip_region))
+       {
+         handle_cursor = TRUE;
+         gdk_fb_cursor_hide ();
+       }
+      
+      x += private->abs_x;
+      y += private->abs_y;
+  
+      if (x <  private->llim_x)
+       {
+         width -= private->llim_x - x;
+         x = private->llim_x;
+       }
+      if (x + width >  private->lim_x)
+       width =  private->lim_x - x;
+      
+      if (y <  private->llim_y)
+       {
+         height -= private->llim_y - y;
+         y = private->llim_y;
+       }
+      if (y + height >  private->lim_y)
+       height =  private->lim_y - y;
+
+      tmprect.x = x;
+      tmprect.y = y;
+      tmprect.width = width;
+      tmprect.height = height;
+      tmpreg = gdk_region_rectangle (&tmprect);
+      
+      gdk_region_intersect (tmpreg, real_clip_region);
+      
+      for (i = 0; i < tmpreg->numRects; i++)
+       {
+         GdkRectangle r;
+         r.x = tmpreg->rects[i].x1;
+         r.y = tmpreg->rects[i].y1;
+         r.width = tmpreg->rects[i].x2 - tmpreg->rects[i].x1;
+         r.height = tmpreg->rects[i].y2 - tmpreg->rects[i].y1;
+
+         if ((r.width > 0) && (r.height > 0))
+           (GDK_GC_FBDATA (gc)->fill_rectangle) (drawable, gc, &r, &color);
+       }
+      
+      gdk_region_destroy (tmpreg);
+      
+      gdk_region_destroy (real_clip_region);
+      if (handle_cursor)
+       gdk_fb_cursor_unhide ();
     }
   else
     {
       GdkPoint pts[5];
+      
       pts[0].x = pts[4].x = x;
       pts[0].y = pts[4].y = y;
       pts[1].x = x + width;
@@ -1735,6 +762,7 @@ gdk_fb_draw_rectangle (GdkDrawable    *drawable,
       pts[3].y = y + height;
       gdk_fb_draw_lines (drawable, gc, pts, 5);
     }
+
 }
 
 static void
@@ -1743,17 +771,17 @@ gdk_fb_draw_points (GdkDrawable    *drawable,
                    GdkPoint       *points,
                    gint            npoints)
 {
-  GdkRectangle *rects = g_alloca (npoints * sizeof(GdkRectangle));
+  GdkSpan *spans = g_alloca (npoints * sizeof(GdkSpan));
   int i;
 
   for (i = 0; i < npoints; i++)
     {
-      rects[i].x = points[i].x;
-      rects[i].y = points[i].y;
-      rects[i].width = rects[i].height = 1;
+      spans[i].x = points[i].x;
+      spans[i].y = points[i].y;
+      spans[i].width = 1;
     }
 
-  gdk_fb_fill_spans (drawable, gc, rects, npoints);
+  gdk_fb_fill_spans (drawable, gc, spans, npoints, FALSE);
 }
 
 static void
@@ -1801,7 +829,7 @@ gdk_fb_draw_polygon (GdkDrawable    *drawable,
     }
 }
 
-static void
+void
 gdk_fb_draw_lines (GdkDrawable    *drawable,
                   GdkGC          *gc,
                   GdkPoint       *points,
index 89ae218e9054a60f9d2457b49486872416624043..3a6002c06ab26a5af02d292576d25a4ffa58781a 100644 (file)
 #include "gdkinternals.h"
 #include "gdkfb.h"
 
-#include "gdkkeysyms.h"
-
-#if HAVE_CONFIG_H
-#  include <config.h>
-#  if STDC_HEADERS
-#    include <string.h>
-#  endif
-#endif
-
-typedef struct _GdkIOClosure GdkIOClosure;
-typedef struct _GdkEventPrivate GdkEventPrivate;
-
-#define DOUBLE_CLICK_TIME      250
-#define TRIPLE_CLICK_TIME      500
-#define DOUBLE_CLICK_DIST      5
-#define TRIPLE_CLICK_DIST      5
-
-typedef enum
-{
-  /* Following flag is set for events on the event queue during
-   * translation and cleared afterwards.
-   */
-  GDK_EVENT_PENDING = 1 << 0
-} GdkEventFlags;
-
-struct _GdkIOClosure
-{
-  GdkInputFunction function;
-  GdkInputCondition condition;
-  GdkDestroyNotify notify;
-  gpointer data;
-};
-
-struct _GdkEventPrivate
-{
-  GdkEvent event;
-  guint    flags;
-};
-
-/* 
- * Private function declarations
- */
-
-/* Private variable declarations
- */
-
-#if 0
-static GList *client_filters;              /* Filters for client messages */
-
-static GSourceFuncs event_funcs = {
-  gdk_event_prepare,
-  gdk_event_check,
-  gdk_event_dispatch,
-  (GDestroyNotify)g_free
-};
-#endif
-
 /*********************************************
  * Functions for maintaining the event queue *
  *********************************************/
@@ -101,6 +44,15 @@ static gboolean fb_events_dispatch (gpointer  source_data,
                                    GTimeVal *dispatch_time,
                                    gpointer  user_data);
 
+guint32
+gdk_fb_get_time(void)
+{
+  GTimeVal tv;
+
+  g_get_current_time (&tv);
+  return (guint32) tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
 void 
 gdk_events_init (void)
 {
index bf1e030518c19a44e2850e64dc56c28972ad9e5c..b0087e0e639414cedc3709e6aabd6b39e37f1c27 100644 (file)
@@ -76,9 +76,6 @@ static Keyboard * tty_keyboard_open(void);
 static MouseDevice *gdk_fb_mouse = NULL;
 static Keyboard *keyboard = NULL;
 
-static guint multiclick_tag;
-static GdkEvent *multiclick_event = NULL;
-
 #ifndef VESA_NO_BLANKING
 #define VESA_NO_BLANKING        0
 #define VESA_VSYNC_SUSPEND      1
@@ -110,33 +107,11 @@ input_activity (void)
 #endif
 }
 
-static gboolean
-click_event_timeout (gpointer x)
-{
-  switch (multiclick_event->type)
-    {
-    case GDK_BUTTON_RELEASE:
-      gdk_event_free (multiclick_event);
-      break;
-    case GDK_2BUTTON_PRESS:
-    case GDK_3BUTTON_PRESS:
-      gdk_event_queue_append (multiclick_event);
-      break;
-    default:
-      break;
-    }
-
-  multiclick_event = NULL;
-  multiclick_tag = 0;
-
-  return FALSE;
-}
-
 static void
 send_button_event (MouseDevice *mouse,
                   guint button,
                   gboolean press_event,
-                  time_t the_time)
+                  guint32 the_time)
 {
   GdkEvent *event;
   gint x, y;
@@ -152,35 +127,6 @@ send_button_event (MouseDevice *mouse,
   x = mouse->x - x;
   y = mouse->y - y;
 
-  if (!press_event &&
-      multiclick_event &&
-      multiclick_event->button.button == button &&
-      multiclick_event->button.window == window &&
-      ABS(multiclick_event->button.x - x) < 3 &&
-      ABS(multiclick_event->button.y - y) < 3)
-    {
-      multiclick_event->button.time = the_time;
-
-      /* Just change multiclick_event into a different event */
-      switch (multiclick_event->button.type)
-       {
-       default:
-         g_assert_not_reached ();
-
-       case GDK_BUTTON_RELEASE:
-         multiclick_event->button.type = GDK_2BUTTON_PRESS;
-         return;
-
-       case GDK_2BUTTON_PRESS:
-         multiclick_event->button.type = GDK_3BUTTON_PRESS;
-         return;
-
-       case GDK_3BUTTON_PRESS:
-         gdk_event_queue_append (multiclick_event); multiclick_event = NULL;
-         g_source_remove (multiclick_tag); multiclick_tag = 0;
-       }
-    }
-
   event = gdk_event_make (window, press_event ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE, FALSE);
 
   if (!event)
@@ -219,6 +165,8 @@ send_button_event (MouseDevice *mouse,
       mouse->click_grab = FALSE;
     }
 
+  event->button.time = the_time;
+  
 #if 0
   g_message ("Button #%d %s [%d, %d] in %p",
             button, press_event?"pressed":"released",
@@ -237,11 +185,9 @@ send_button_event (MouseDevice *mouse,
     }
 #endif
 
-  if (!press_event && !multiclick_tag)
-    {
-      multiclick_tag = g_timeout_add (250, click_event_timeout, NULL);
-      multiclick_event = gdk_event_copy (event);
-    }
+  /* For double-clicks */
+  if (press_event)
+    gdk_event_button_generate (event);
 
   gdk_event_queue_append (event);
 }
@@ -598,6 +544,7 @@ handle_mouse_input(MouseDevice *mouse,
       event->motion.device = gdk_core_pointer;
       event->motion.x_root = mouse->x;
       event->motion.y_root = mouse->y;
+      event->motion.time = gdk_fb_get_time ();
     }
 
   if (win != mouse->prev_window)
@@ -732,11 +679,10 @@ handle_input_fidmour (GIOChannel *gioc,
   gdouble x, y, oldx, oldy;
   gboolean got_motion = FALSE;
   gboolean btn_down;
-  time_t the_time;
-  GTimeVal tv;
+  guint32 the_time;
 
-  g_get_current_time (&tv);
-  the_time = tv.tv_sec;
+  the_time = gdk_fb_get_time ();
+  
   oldx = mouse->x;
   oldy = mouse->y;
   while (pull_fidmour_packet (mouse, &btn_down, &x, &y))
@@ -775,13 +721,11 @@ handle_input_ps2 (GIOChannel *gioc,
   MouseDevice *mouse = data;
   int n, dx=0, dy=0;
   gboolean new_button1, new_button2, new_button3;
-  time_t the_time;
-  GTimeVal curtime;
+  guint32 the_time;
   gboolean got_motion = FALSE;
   guchar *buf;
 
-  g_get_current_time (&curtime);
-  the_time = curtime.tv_usec;
+  the_time = gdk_fb_get_time ();
 
   while (1) /* Go through as many mouse events as we can */
     {
@@ -862,11 +806,9 @@ handle_input_ms (GIOChannel *gioc,
   guchar byte1, byte2, byte3;
   int n, dx=0, dy=0;
   gboolean new_button1, new_button2, new_button3;
-  time_t the_time;
-  GTimeVal curtime;
+  guint32 the_time;
 
-  g_get_current_time (&curtime);
-  the_time = curtime.tv_usec;
+  the_time = gdk_fb_get_time ();
 
   n = read (mouse->fd, &byte1, 1);
   if ( (n!=1) || (byte1 & 0x40) != 0x40)
@@ -1405,16 +1347,14 @@ handle_mediumraw_keyboard_input (GIOChannel *gioc,
   guchar buf[128];
   int i, n;
   Keyboard *k = data;
-  time_t now;
-  GTimeVal curtime;
+  guint32 now;
 
   n = read (k->fd, buf, sizeof(buf));
   if (n <= 0)
     g_error("Nothing from keyboard!");
 
   /* Now turn this into a keyboard event */
-  g_get_current_time (&curtime);
-  now = curtime.tv_sec;
+  now = gdk_fb_get_time ();
 
   for (i = 0; i < n; i++)
     {
@@ -1556,16 +1496,14 @@ handle_xlate_keyboard_input (GIOChannel *gioc,
   guchar buf[128];
   int i, n;
   Keyboard *k = data;
-  time_t now;
-  GTimeVal curtime;
+  guint32 now;
 
   n = read (k->fd, buf, sizeof(buf));
   if (n <= 0)
     g_error ("Nothing from keyboard!");
 
   /* Now turn this into a keyboard event */
-  g_get_current_time (&curtime);
-  now = curtime.tv_sec;
+  now = gdk_fb_get_time ();
 
   for (i = 0; i < n; i++)
     {
index 5ffac036ef3d377f2d80cb144a78d9f55a59de5a..b1d95548f81c931c935c25d047e7129252887e3b 100644 (file)
@@ -991,10 +991,9 @@ gdk_event_make (GdkWindow *window,
       guint32 the_time = g_latest_time.tv_sec * 1000 + g_latest_time.tv_usec / 1000;
 #else
       guint32 the_time;
-      GTimeVal gcurtime;
 
-       g_get_current_time (&gcurtime);
-       the_time = gcurtime.tv_sec * 1000 + gcurtime.tv_usec / 1000;
+      
+      the_time = gdk_fb_get_time ();
 #endif
 
       event->any.type = type;
index f3708338a089184d64fb48e5f39e30494e1fc690..6ae7fc63def1e3455801085bbb3b8284431b71cc 100644 (file)
@@ -215,7 +215,7 @@ typedef struct {
   /* These functions can only be called for drawables
    * that have the same depth as the gc. 
    */
-  void        (*set_pixel) (GdkDrawable    *drawable,
+  void (*set_pixel)        (GdkDrawable    *drawable,
                            GdkGC          *gc,
                            int             x,
                            int             y,
@@ -227,11 +227,16 @@ typedef struct {
                            int               y,
                            GdkColor         *color);
   
-  void        (*fill_span) (GdkDrawable *drawable,
-                           GdkGC       *gc,
-                           GdkSegment  *cur,
-                           GdkColor    *color);
-
+  void (*fill_span)        (GdkDrawable  *drawable,
+                           GdkGC        *gc,
+                           GdkSpan      *span,
+                           GdkColor     *color);
+
+  void (*fill_rectangle)   (GdkDrawable  *drawable,
+                           GdkGC        *gc,
+                           GdkRectangle *rect,
+                           GdkColor     *color);
+  
   gdk_fb_draw_drawable_func *draw_drawable[GDK_NUM_FB_SRCBPP];
 } GdkGCFBData;
 
@@ -301,51 +306,67 @@ struct _GdkFBDrawingContext {
   gboolean handle_cursor : 1;
 };
 
-void gdk_fb_drawing_context_init(GdkFBDrawingContext *dc, GdkDrawable *drawable,
-                                GdkGC *gc, gboolean draw_bg, gboolean do_clipping);
-void gdk_fb_drawing_context_finalize(GdkFBDrawingContext *dc);
-
-void gdk_fb_draw_drawable_3 (GdkDrawable *drawable,
-                            GdkGC *gc,
-                            GdkPixmap *src,
-                            GdkFBDrawingContext *dc,
-                            gint xsrc,
-                            gint ysrc,
-                            gint xdest,
-                            gint ydest,
-                            gint width,
-                            gint height);
-
-void gdk_fb_draw_drawable_2 (GdkDrawable *drawable,
-                            GdkGC       *gc,
-                            GdkPixmap   *src,
-                            gint         xsrc,
-                            gint         ysrc,
-                            gint         xdest,
-                            gint         ydest,
-                            gint         width,
-                            gint         height,
-                            gboolean     draw_bg,
-                            gboolean     do_clipping);
-void gdk_fb_draw_rectangle (GdkDrawable    *drawable,
-                           GdkGC          *gc,
-                           gint            filled,
-                           gint            x,
-                           gint            y,
-                           gint            width,
-                           gint            height);
-void gdk_fb_fill_spans(GdkDrawable *real_drawable, GdkGC *gc, GdkRectangle *rects, int nrects);
-GdkRegion *gdk_fb_clip_region(GdkDrawable *drawable, GdkGC *gc, gboolean do_clipping, gboolean do_children);
-
-GdkGrabStatus
-gdk_fb_pointer_grab (GdkWindow *         window,
-                    gint                 owner_events,
-                    GdkEventMask         event_mask,
-                    GdkWindow *          confine_to,
-                    GdkCursor *          cursor,
-                    guint32  time,
-                    gboolean implicit_grab);
-void gdk_fb_pointer_ungrab (guint32 time, gboolean implicit_grab);
+void       gdk_fb_drawing_context_init     (GdkFBDrawingContext *dc,
+                                           GdkDrawable         *drawable,
+                                           GdkGC               *gc,
+                                           gboolean             draw_bg,
+                                           gboolean             do_clipping);
+void       gdk_fb_drawing_context_finalize (GdkFBDrawingContext *dc);
+void       gdk_fb_draw_drawable_3          (GdkDrawable         *drawable,
+                                           GdkGC               *gc,
+                                           GdkPixmap           *src,
+                                           GdkFBDrawingContext *dc,
+                                           gint                 xsrc,
+                                           gint                 ysrc,
+                                           gint                 xdest,
+                                           gint                 ydest,
+                                           gint                 width,
+                                           gint                 height);
+void       gdk_fb_draw_drawable_2          (GdkDrawable         *drawable,
+                                           GdkGC               *gc,
+                                           GdkPixmap           *src,
+                                           gint                 xsrc,
+                                           gint                 ysrc,
+                                           gint                 xdest,
+                                           gint                 ydest,
+                                           gint                 width,
+                                           gint                 height,
+                                           gboolean             draw_bg,
+                                           gboolean             do_clipping);
+void       gdk_fb_draw_rectangle           (GdkDrawable         *drawable,
+                                           GdkGC               *gc,
+                                           gint                 filled,
+                                           gint                 x,
+                                           gint                 y,
+                                           gint                 width,
+                                           gint                 height);
+void       gdk_fb_draw_lines               (GdkDrawable         *drawable,
+                                           GdkGC               *gc,
+                                           GdkPoint            *points,
+                                           gint                 npoints);
+void       gdk_fb_fill_spans               (GdkDrawable         *real_drawable,
+                                           GdkGC               *gc,
+                                           GdkSpan             *spans,
+                                           int                  nspans,
+                                           gboolean             sorted);
+GdkRegion *gdk_fb_clip_region              (GdkDrawable         *drawable,
+                                           GdkGC               *gc,
+                                           gboolean             do_clipping,
+                                           gboolean             do_children);
+
+
+GdkGrabStatus gdk_fb_pointer_grab          (GdkWindow           *window,
+                                           gint                 owner_events,
+                                           GdkEventMask         event_mask,
+                                           GdkWindow           *confine_to,
+                                           GdkCursor           *cursor,
+                                           guint32              time,
+                                           gboolean             implicit_grab);
+void gdk_fb_pointer_ungrab                 (guint32 time,
+                                           gboolean implicit_grab);
+
+guint32 gdk_fb_get_time                    (void);
+
 
 extern GdkWindow *_gdk_fb_pointer_grab_window, *_gdk_fb_pointer_grab_window_events, *_gdk_fb_keyboard_grab_window, *_gdk_fb_pointer_grab_confine;
 extern GdkEventMask _gdk_fb_pointer_grab_events, _gdk_fb_keyboard_grab_events;
diff --git a/gdk/linux-fb/gdkrender-fb.c b/gdk/linux-fb/gdkrender-fb.c
new file mode 100644 (file)
index 0000000..1bcc409
--- /dev/null
@@ -0,0 +1,1154 @@
+#include "gdkprivate-fb.h"
+#include <string.h>
+
+/*
+ * Reading pixel values from a generic drawable.
+ */
+
+static GetPixelRet
+gdk_fb_drawable_get_color (GdkDrawable *drawable,
+                          GdkGC *gc,
+                          int x,
+                          int y,
+                          GdkColor *spot)
+{
+  GetPixelRet retval = GPR_NONE;
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+
+  switch (private->depth)
+    {
+    case 1:
+      {
+       guchar foo = mem[(x >> 3) + y * rowstride];
+       if (foo & (1 << (x % 8)))
+         *spot = GDK_GC_FBDATA (gc)->values.foreground;
+       else
+         {
+           retval = GPR_USED_BG;
+           *spot = GDK_GC_FBDATA (gc)->values.background;
+         }
+      }
+      break;
+    case 71:
+      if (mem[x + y * rowstride])
+       *spot = GDK_GC_FBDATA (gc)->values.foreground;
+      else
+       *spot = GDK_GC_FBDATA (gc)->values.background;
+      break;
+    case 77:
+      retval = GPR_AA_GRAYVAL;
+      spot->pixel = mem[x + y * rowstride] << 1;
+      spot->red = spot->green = spot->blue = spot->pixel << 8;
+      break;
+    case 78: /* AA mode */
+      retval = GPR_AA_GRAYVAL;
+      spot->pixel = mem[x + y * rowstride];
+      spot->red = spot->green = spot->blue = spot->pixel << 8;
+      break;
+    case 8:
+      spot->pixel = mem[x + y * rowstride];
+      *spot = private->colormap->colors[spot->pixel];
+      break;
+    case 16:
+      {
+       guint16 val16 = *((guint16 *)&mem[x*2 + y*rowstride]);
+
+       spot->red = (((1<<gdk_display->modeinfo.red.length) - 1) & (val16 >> gdk_display->modeinfo.red.offset)) << (16 - gdk_display->modeinfo.red.length);
+       spot->green = (((1<<gdk_display->modeinfo.green.length) - 1) & (val16 >> gdk_display->modeinfo.green.offset)) << (16 - gdk_display->modeinfo.green.length);
+       spot->blue = (((1<<gdk_display->modeinfo.blue.length) - 1) & (val16 >> gdk_display->modeinfo.blue.offset)) << (16 - gdk_display->modeinfo.blue.length);
+
+       spot->pixel = val16;
+      }
+      break;
+    case 24:
+      {
+       guchar *smem = &mem[x*3 + y*rowstride];
+       spot->red = smem[gdk_display->red_byte] << 8;
+       spot->green = smem[gdk_display->green_byte] << 8;
+       spot->blue = smem[gdk_display->blue_byte] << 8;
+#if (G_BYTE_ORDER == G_BIG_ENDIAN)
+       spot->pixel = (smem[0]<<16)|(smem[1]<<8)|smem[2];
+#else
+       spot->pixel = smem[0]|(smem[1]<<8)|(smem[2]<<16);
+#endif
+      }
+      break;
+    case 32:
+      {
+       guchar *smem = &mem[x*4 + y*rowstride];
+       spot->red = smem[gdk_display->red_byte] << 8;
+       spot->green = smem[gdk_display->green_byte] << 8;
+       spot->blue = smem[gdk_display->blue_byte] << 8;
+       spot->pixel = *(guint32 *)smem;
+      }
+      break;
+    }
+
+  return retval;
+}
+
+/*************************************
+ * gc->get_color() implementations
+ *************************************/
+
+static GetPixelRet
+gdk_fb_get_color_1 (GdkDrawable *drawable,
+                   GdkGC *gc,
+                   int x,
+                   int y,
+                   GdkColor *color)
+{
+  GetPixelRet retval = GPR_NONE;
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+  guchar foo;
+
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+  
+  foo = mem[(x >> 3) + y * rowstride];
+  if (foo & (1 << (x % 8)))
+    *color = GDK_GC_FBDATA (gc)->values.foreground;
+  else
+    {
+      retval = GPR_USED_BG;
+
+      *color = GDK_GC_FBDATA (gc)->values.background;
+    }
+  
+  return retval;
+}
+
+static GetPixelRet
+gdk_fb_get_color_8 (GdkDrawable *drawable,
+                   GdkGC *gc,
+                   int x,
+                   int y,
+                   GdkColor *color)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+  gint pixel;
+
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+  
+  pixel = mem[x + y * rowstride];
+  *color = private->colormap->colors[pixel];
+
+  return GPR_NONE;
+}
+
+static GetPixelRet
+gdk_fb_get_color_16 (GdkDrawable *drawable,
+                    GdkGC *gc,
+                    int x,
+                    int y,
+                    GdkColor *color)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+  guint16 val16;
+
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+
+  val16 = *((guint16 *)&mem[x*2 + y*rowstride]);
+
+  color->red = (((1<<gdk_display->modeinfo.red.length) - 1) & (val16 >> gdk_display->modeinfo.red.offset)) << (16 - gdk_display->modeinfo.red.length);
+  color->green = (((1<<gdk_display->modeinfo.green.length) - 1) & (val16 >> gdk_display->modeinfo.green.offset)) << (16 - gdk_display->modeinfo.green.length);
+  color->blue = (((1<<gdk_display->modeinfo.blue.length) - 1) & (val16 >> gdk_display->modeinfo.blue.offset)) << (16 - gdk_display->modeinfo.blue.length);
+
+  color->pixel = val16;
+
+  return GPR_NONE;
+}
+
+static GetPixelRet
+gdk_fb_get_color_24 (GdkDrawable *drawable,
+                    GdkGC *gc,
+                    int x,
+                    int y,
+                    GdkColor *color)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+  guchar *smem;
+
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+
+  smem = &mem[x*3 + y*rowstride];
+  color->red = smem[gdk_display->red_byte] << 8;
+  color->green = smem[gdk_display->green_byte] << 8;
+  color->blue = smem[gdk_display->blue_byte] << 8;
+#if (G_BYTE_ORDER == G_BIG_ENDIAN)
+  color->pixel = (smem[0]<<16)|(smem[1]<<8)|smem[2];
+#else
+  color->pixel = smem[0]|(smem[1]<<8)|(smem[2]<<16);
+#endif
+
+  return GPR_NONE;
+}
+
+static GetPixelRet
+gdk_fb_get_color_32 (GdkDrawable *drawable,
+                    GdkGC *gc,
+                    int x,
+                    int y,
+                    GdkColor *color)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+  guchar *smem;
+
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+  
+  smem = &mem[x*4 + y*rowstride];
+  color->red = smem[gdk_display->red_byte] << 8;
+  color->green = smem[gdk_display->green_byte] << 8;
+  color->blue = smem[gdk_display->blue_byte] << 8;
+  color->pixel = *(guint32 *)smem;
+
+  return GPR_NONE;
+}
+
+/*************************************
+ * gc->set_pixel() implementations
+ *************************************/
+
+static void
+gdk_fb_set_pixel_1(GdkDrawable *drawable,
+                  GdkGC *gc,
+                  int x,
+                  int y,
+                  gulong pixel)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+  guchar *ptr;
+
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+  
+  ptr = mem + (y*rowstride) + (x >> 3);
+
+  if (pixel)
+    *ptr |= (1 << (x % 8));
+  else
+    *ptr &= ~(1 << (x % 8));
+}
+
+static void
+gdk_fb_set_pixel_8(GdkDrawable *drawable,
+                  GdkGC *gc,
+                  int x,
+                  int y,
+                  gulong pixel)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+
+  mem[x + y*rowstride] = pixel;
+}
+
+static void
+gdk_fb_set_pixel_16(GdkDrawable *drawable,
+                   GdkGC *gc,
+                   int x,
+                   int y,
+                   gulong pixel)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+  guint16 *ptr;
+
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+  
+  ptr = (guint16 *)&mem[x*2 + y*rowstride];
+  *ptr = pixel;
+}
+
+static void
+gdk_fb_set_pixel_24(GdkDrawable *drawable,
+                   GdkGC *gc,
+                   int x,
+                   int y,
+                   gulong pixel)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+  guchar *smem;
+  
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+  
+  smem = &mem[x*3 + y*rowstride];
+  smem[0] = pixel & 0xff;
+  smem[1] = (pixel >> 8) & 0xff;
+  smem[2] = (pixel >> 16) & 0xff;
+}
+
+static void
+gdk_fb_set_pixel_32(GdkDrawable *drawable,
+                   GdkGC *gc,
+                   int x,
+                   int y,
+                   gulong pixel)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  guchar *mem = private->mem;
+  guint rowstride = private->rowstride;
+  guint32 *smem;
+
+  g_assert (private->depth == GDK_GC_FBDATA (gc)->depth);
+  
+  smem = (guint32 *)&mem[x*4 + y*rowstride];
+  *smem = pixel;
+}
+
+
+/*************************************
+ * gc->fill_span() implementations
+ *************************************/
+
+static void
+gdk_fb_fill_span_generic (GdkDrawable *drawable,
+                         GdkGC       *gc,
+                         GdkSpan     *span,
+                         GdkColor    *color)
+{
+  int curx;
+  GdkColor spot = *color;
+  GdkGCFBData *gc_private;
+  GdkDrawableFBData *private;
+  gint left, right, y;
+  int clipxoff, clipyoff; /* Amounts to add to curx & cury to get x & y in clip mask */
+  int tsxoff, tsyoff;
+  GdkDrawable *cmask;
+  guchar *clipmem;
+  guint mask_rowstride;
+  GdkPixmap *ts = NULL;
+  GdkDrawableFBData *ts_private;
+  gboolean solid_stipple;
+  GdkFunction func;
+
+  private = GDK_DRAWABLE_FBDATA (drawable);
+  gc_private = GDK_GC_FBDATA (gc);
+
+  g_assert (gc);
+
+  y = span->y;
+  left = span->x;
+  right = span->x + span->width;
+  
+  func = gc_private->values.function;
+    
+  cmask = gc_private->values.clip_mask;
+  clipxoff = clipyoff = tsxoff = tsyoff = 0;
+  mask_rowstride = 0;
+  solid_stipple = FALSE;
+  clipmem = NULL;
+  
+  if (cmask)
+    {
+      GdkDrawableFBData *cmask_private;
+      
+      cmask_private = GDK_DRAWABLE_IMPL_FBDATA (cmask);
+      
+      clipmem = cmask_private->mem;
+      clipxoff = cmask_private->abs_x - gc_private->values.clip_x_origin - private->abs_x;
+      clipyoff = cmask_private->abs_y - gc_private->values.clip_y_origin - private->abs_y;
+      mask_rowstride = cmask_private->rowstride;
+    }
+  
+  if (gc_private->values.fill == GDK_TILED &&
+      gc_private->values.tile)
+    {
+      gint xstep;
+      gint relx, rely;
+      int drawh;
+      GdkFBDrawingContext *dc, dc_data;
+      
+      dc = &dc_data;
+      
+      gdk_fb_drawing_context_init (dc, drawable, gc, FALSE, TRUE);
+      
+      ts = gc_private->values.tile;
+      ts_private = GDK_DRAWABLE_IMPL_FBDATA (ts);
+      
+      rely = y - private->abs_y;
+      drawh = (rely + gc_private->values.ts_y_origin) % ts_private->height;
+      if (drawh < 0)
+       drawh += GDK_DRAWABLE_FBDATA (ts)->height;
+      
+      for (curx = left; curx < right; curx += xstep)
+       {
+         int draww;
+         
+         relx = curx - private->abs_x;
+         
+         draww = (relx + gc_private->values.ts_x_origin) % ts_private->width;
+         if (draww < 0)
+           draww += ts_private->width;
+         
+         xstep = MIN (ts_private->width - draww, right - relx);
+         
+         gdk_fb_draw_drawable_3 (drawable, gc, GDK_DRAWABLE_IMPL (ts),
+                                 dc,
+                                 draww, drawh,
+                                 relx, rely,
+                                 xstep, 1);
+       }
+      
+      gdk_fb_drawing_context_finalize (dc);
+      
+      return;
+    }
+  else if ((gc_private->values.fill == GDK_STIPPLED ||
+           gc_private->values.fill == GDK_OPAQUE_STIPPLED) &&
+          gc_private->values.stipple)
+    {
+      ts = gc_private->values.stipple;
+      tsxoff = GDK_DRAWABLE_FBDATA (ts)->abs_x - gc_private->values.ts_x_origin - private->abs_x;
+      tsyoff = GDK_DRAWABLE_FBDATA (ts)->abs_y - gc_private->values.ts_y_origin - private->abs_y;
+      solid_stipple = (gc_private->values.fill == GDK_OPAQUE_STIPPLED);
+    }
+  
+  for (curx = left; curx < right; curx++)
+    {
+      int maskx = curx+clipxoff, masky = y + clipyoff;
+      guchar foo;
+      
+      if (cmask)
+       {
+         foo = clipmem[masky*mask_rowstride + (maskx >> 3)];
+         
+         if (!(foo & (1 << (maskx % 8))))
+           continue;
+       }
+      
+      if (func == GDK_INVERT)
+       {
+         (gc_private->get_color) (drawable, gc, curx, y, &spot);
+         spot.pixel = ~spot.pixel;
+         spot.red = ~spot.red;
+         spot.green = ~spot.green;
+         spot.blue = ~spot.blue;
+       }
+      else if (ts)
+       {
+         int wid, hih;
+         
+         ts_private = GDK_DRAWABLE_IMPL_FBDATA (ts);
+         
+         wid = ts_private->width;
+         hih = ts_private->height;
+         
+         maskx = (curx+tsxoff)%wid;
+         masky = (y+tsyoff)%hih;
+         if (maskx < 0)
+           maskx += wid;
+         if (masky < 0)
+           masky += hih;
+         
+         foo = ts_private->mem[(maskx >> 3) + ts_private->rowstride*masky];
+         if (foo & (1 << (maskx % 8)))
+           {
+             spot = gc_private->values.foreground;
+           }
+         else if (solid_stipple)
+           {
+             spot = gc_private->values.background;
+           }
+         else
+           continue;
+       }
+      
+      (gc_private->set_pixel) (drawable, gc, curx, y, spot.pixel);
+    }
+}
+
+static void
+gdk_fb_fill_span_simple_1 (GdkDrawable *drawable,
+                          GdkGC       *gc,
+                          GdkSpan     *span,
+                          GdkColor    *color)
+{
+  int curx;
+  GdkGCFBData *gc_private;
+  GdkDrawableFBData *private;
+  guchar *mem, *ptr;
+  guint rowstride;
+  gint left, right, y;
+
+  private = GDK_DRAWABLE_FBDATA (drawable);
+  gc_private = GDK_GC_FBDATA (gc);
+
+  g_assert (gc);
+
+  g_assert (!gc_private->values.clip_mask &&
+           !gc_private->values.tile &&
+           !gc_private->values.stipple &&
+           gc_private->values.function != GDK_INVERT);
+
+  y = span->y;
+  left = span->x;
+  right = span->x + span->width;
+  
+  mem = private->mem;
+  rowstride = private->rowstride;
+
+  {
+    int fromx = MIN ((left+7)&(~7), right);
+    int begn = fromx - left, begoff = left % 8, endn;
+    guchar begmask, endmask;
+    int body_end = right & ~7;
+    int body_len = (body_end - fromx)/8;
+    
+    begmask = ((1 << (begn + begoff)) - 1)
+      & ~((1 << (begoff)) - 1);
+    endn = right - body_end;
+    endmask = (1 << endn) - 1;
+    
+    ptr = mem + y*rowstride + (left >> 3);
+       
+    if (color->pixel)
+      *ptr |= begmask;
+    else
+      *ptr &= ~begmask;
+    
+    curx = fromx;
+    
+    if (curx < right)
+      {
+       ptr = mem + y*rowstride + (curx >> 3);
+       memset (ptr, color->pixel?0xFF:0, body_len);
+       
+       if (endn)
+         {
+           ptr = mem + y*rowstride + (body_end >> 3);
+           if (color->pixel)
+             *ptr |= endmask;
+           else
+             *ptr &= ~endmask;
+         }
+      }
+  }
+}
+
+static void
+gdk_fb_fill_span_simple_8 (GdkDrawable *drawable,
+                          GdkGC       *gc,
+                          GdkSpan     *span,
+                          GdkColor    *color)
+{
+  GdkGCFBData *gc_private;
+  GdkDrawableFBData *private;
+  guchar *mem, *ptr;
+  guint rowstride;
+
+  private = GDK_DRAWABLE_FBDATA (drawable);
+  gc_private = GDK_GC_FBDATA (gc);
+
+  g_assert (gc);
+
+  g_assert (!gc_private->values.clip_mask &&
+           !gc_private->values.tile &&
+           !gc_private->values.stipple &&
+           gc_private->values.function != GDK_INVERT);
+
+  mem = private->mem;
+  rowstride = private->rowstride;
+
+  ptr = mem + span->y*rowstride + span->x;
+  memset (ptr, color->pixel, span->width);
+}
+static void
+gdk_fb_fill_span_simple_16 (GdkDrawable *drawable,
+                           GdkGC       *gc,
+                           GdkSpan     *span,
+                           GdkColor    *color)
+{
+  GdkGCFBData *gc_private;
+  GdkDrawableFBData *private;
+  guchar *mem;
+  guint rowstride;
+  guint16 *p16;
+  int n;
+  int i;
+
+  private = GDK_DRAWABLE_FBDATA (drawable);
+  gc_private = GDK_GC_FBDATA (gc);
+
+  g_assert (gc);
+
+  g_assert (!gc_private->values.clip_mask &&
+           !gc_private->values.tile &&
+           !gc_private->values.stipple &&
+           gc_private->values.function != GDK_INVERT);
+
+  mem = private->mem;
+  rowstride = private->rowstride;
+
+  n = span->width;
+  p16 = (guint16 *)(mem + span->y * rowstride + span->x*2);
+  for (i = 0; i < n; i++)
+    *(p16++) = color->pixel;
+}
+
+static void
+gdk_fb_fill_span_simple_24 (GdkDrawable *drawable,
+                           GdkGC       *gc,
+                           GdkSpan     *span,
+                           GdkColor    *color)
+{
+  GdkGCFBData *gc_private;
+  GdkDrawableFBData *private;
+  guchar *mem, *ptr;
+  guint rowstride;
+  int n;
+  guchar redval, greenval, blueval;
+  guchar *firstline, *ptr_end;
+
+  private = GDK_DRAWABLE_FBDATA (drawable);
+  gc_private = GDK_GC_FBDATA (gc);
+
+  g_assert (gc);
+
+  g_assert (!gc_private->values.clip_mask &&
+           !gc_private->values.tile &&
+           !gc_private->values.stipple &&
+           gc_private->values.function != GDK_INVERT);
+
+  mem = private->mem;
+  rowstride = private->rowstride;
+
+  redval = color->red>>8;
+  greenval = color->green>>8;
+  blueval = color->blue>>8;
+    
+  n = span->width*3;
+    
+  firstline = ptr = mem + span->y * rowstride + span->x*3;
+  ptr_end = ptr+n;
+  while (ptr < ptr_end)
+    {
+      ptr[gdk_display->red_byte] = redval;
+      ptr[gdk_display->green_byte] = greenval;
+      ptr[gdk_display->blue_byte] = blueval;
+      ptr += 3;
+    }
+}
+static void
+gdk_fb_fill_span_simple_32 (GdkDrawable *drawable,
+                           GdkGC       *gc,
+                           GdkSpan     *span,
+                           GdkColor    *color)
+{
+  GdkGCFBData *gc_private;
+  GdkDrawableFBData *private;
+  guchar *mem;
+  guint rowstride;
+  guint32 *p32;
+  int n;
+  int i;
+
+  private = GDK_DRAWABLE_FBDATA (drawable);
+  gc_private = GDK_GC_FBDATA (gc);
+
+  g_assert (gc);
+
+  g_assert (!gc_private->values.clip_mask &&
+           !gc_private->values.tile &&
+           !gc_private->values.stipple &&
+           gc_private->values.function != GDK_INVERT);
+
+  mem = private->mem;
+  rowstride = private->rowstride;
+
+  n = span->width;
+  p32 = (guint32 *)(mem + span->y * rowstride + span->x*4);
+  for (i = 0; i < n; i++)
+    *(p32++) = color->pixel;
+}
+
+
+/*************************************
+ * gc->draw_drawable() implementations
+ *************************************/
+
+static void
+gdk_fb_draw_drawable_generic (GdkDrawable *drawable,
+                             GdkGC       *gc,
+                             GdkPixmap   *src,
+                             GdkFBDrawingContext *dc,
+                             gint         start_y,
+                             gint         end_y,
+                             gint         start_x,
+                             gint         end_x,
+                             gint         src_x_off,
+                             gint         src_y_off,
+                             gint         draw_direction)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  int cur_x, cur_y;
+
+  for (cur_y = start_y; cur_y*draw_direction < end_y*draw_direction; cur_y+=draw_direction)
+    {
+      for (cur_x = start_x; cur_x < end_x; cur_x++)
+       {
+         GdkColor spot;
+         
+         if (GDK_GC_FBDATA(gc)->values.clip_mask)
+           {
+             int maskx = cur_x + dc->clipxoff, masky = cur_y + dc->clipyoff;
+             guchar foo;
+             
+             foo = dc->clipmem[masky*dc->clip_rowstride + (maskx >> 3)];
+             
+             if (!(foo & (1 << (maskx % 8))))
+               continue;
+           }
+         
+         switch (gdk_fb_drawable_get_color (src, gc, cur_x + src_x_off, cur_y + src_y_off, &spot))
+           {
+           case GPR_AA_GRAYVAL:
+             {
+               GdkColor realspot, fg;
+               guint graylevel = spot.pixel;
+               gint tmp;
+               
+               if (private->depth == 1)
+                 {
+                   if (spot.pixel > 192)
+                     spot = GDK_GC_FBDATA (gc)->values.foreground;
+                   else
+                     spot = GDK_GC_FBDATA (gc)->values.background;
+                   break;
+                 }
+               else
+                 {
+                   if (graylevel >= 254)
+                     {
+                       spot = GDK_GC_FBDATA (gc)->values.foreground;
+                     }
+                   else if (graylevel <= 2)
+                     {
+                       if (!dc->draw_bg)
+                         continue;
+                       
+                       spot = GDK_GC_FBDATA (gc)->values.background;
+                     }
+                   else
+                     {
+                       switch ((GDK_GC_FBDATA (gc)->get_color) (drawable, gc, cur_x, cur_y, &realspot))
+                         {
+                         case GPR_USED_BG:
+                           {
+                             int bgx, bgy;
+                             
+                             bgx = (cur_x - GDK_DRAWABLE_IMPL_FBDATA (dc->bg_relto)->abs_x) % GDK_DRAWABLE_IMPL_FBDATA (dc->bgpm)->width + private->abs_x;
+                             bgy = (cur_y - GDK_DRAWABLE_IMPL_FBDATA (dc->bg_relto)->abs_y) % GDK_DRAWABLE_IMPL_FBDATA (dc->bgpm)->height + private->abs_y;
+                             gdk_fb_drawable_get_color (dc->bgpm, gc, bgx, bgy, &realspot);
+                           }
+                           break;
+                         case GPR_NONE:
+                           break;
+                         default:
+                           g_assert_not_reached ();
+                           break;
+                         }
+                       
+                       fg = GDK_GC_FBDATA (gc)->values.foreground;
+
+                       /* Now figure out what 'spot' should actually look like */
+                       fg.red >>= 8;
+                       fg.green >>= 8;
+                       fg.blue >>= 8;
+                       realspot.red >>= 8;
+                       realspot.green >>= 8;
+                       realspot.blue >>= 8;
+
+                               
+                       tmp = (fg.red - realspot.red) * graylevel;
+                       spot.red = realspot.red + ((tmp + (tmp >> 8) + 0x80) >> 8);
+                       spot.red <<= 8;
+                       
+                       tmp = (fg.green - realspot.green) * graylevel;
+                       spot.green = realspot.green + ((tmp + (tmp >> 8) + 0x80) >> 8);
+                       spot.green <<= 8;
+                       
+                       tmp = (fg.blue - realspot.blue) * graylevel;
+                       spot.blue = realspot.blue + ((tmp + (tmp >> 8) + 0x80) >> 8);
+                       spot.blue <<= 8;
+                       
+                       /* Now find the pixel for this thingie */
+                       switch (private->depth)
+                         {
+                         case 8:
+                           if (!gdk_colormap_alloc_color (private->colormap, &spot, FALSE, TRUE))
+                             {
+                               g_error ("Can't allocate AA color!");
+                             }
+                           break;
+                         case 16:
+                           spot.pixel = (spot.red >> (16 - gdk_display->modeinfo.red.length)) << gdk_display->modeinfo.red.offset;
+                           spot.pixel |= (spot.green >> (16 - gdk_display->modeinfo.green.length)) << gdk_display->modeinfo.green.offset;
+                           spot.pixel |= (spot.blue >> (16 - gdk_display->modeinfo.blue.length)) << gdk_display->modeinfo.blue.offset;
+                           break;
+                         case 24:
+                         case 32:
+                           spot.pixel = ((spot.red & 0xFF00) >> 8  << (gdk_display->modeinfo.red.offset))
+                             | ((spot.green & 0xFF00) >> 8 << (gdk_display->modeinfo.green.offset))
+                             | ((spot.blue & 0xFF00) >> 8 << (gdk_display->modeinfo.blue.offset));
+                           break;
+                         }
+                     }
+                 }
+             }
+             break;
+           case GPR_USED_BG:
+             if (!dc->draw_bg)
+               continue;
+             break;
+           case GPR_NONE:
+             break;
+           default:
+             g_assert_not_reached ();
+             break;
+           }
+         
+         (GDK_GC_FBDATA (gc)->set_pixel) (drawable, gc, cur_x, cur_y, spot.pixel);
+       }
+    }
+
+}
+
+void
+gdk_fb_draw_drawable_memmove (GdkDrawable *drawable,
+                             GdkGC       *gc,
+                             GdkPixmap   *src,
+                             GdkFBDrawingContext *dc,
+                             gint         start_y,
+                             gint         end_y,
+                             gint         start_x,
+                             gint         end_x,
+                             gint         src_x_off,
+                             gint         src_y_off,
+                             gint         draw_direction)
+{
+  GdkDrawableFBData *src_private = GDK_DRAWABLE_FBDATA (src);
+  guint depth = src_private->depth;
+  guint src_rowstride = src_private->rowstride;
+  guchar *srcmem = src_private->mem;
+  int linelen = (end_x - start_x)*(depth>>3);
+  gint cur_y;
+  
+  for(cur_y = start_y; cur_y*draw_direction < end_y*draw_direction; cur_y += draw_direction)
+    {
+      memmove (dc->mem + (cur_y * dc->rowstride) + start_x*(depth>>3),
+              srcmem + ((cur_y + src_y_off)*src_rowstride) + (start_x + src_x_off)*(depth>>3),
+              linelen);
+    }
+
+}
+
+static void
+gdk_fb_draw_drawable_aa_24 (GdkDrawable *drawable,
+                           GdkGC       *gc,
+                           GdkPixmap   *src,
+                           GdkFBDrawingContext *dc,
+                           gint         start_y,
+                           gint         end_y,
+                           gint         start_x,
+                           gint         end_x,
+                           gint         src_x_off,
+                           gint         src_y_off,
+                           gint         draw_direction)
+{
+  GdkDrawableFBData *private = GDK_DRAWABLE_FBDATA (drawable);
+  int x, y;
+  GdkGCFBData *gc_private;
+  guchar *dmem = private->mem;
+  guint dst_rowstride = private->rowstride;
+  guchar *smem = GDK_DRAWABLE_FBDATA (src)->mem;
+  guint src_rowstride = GDK_DRAWABLE_FBDATA (src)->rowstride;
+  guchar *dst;
+  guint grayval;
+  gint r, g, b, tmp;
+  GdkColor fg;
+  gint fg_r, fg_g, fg_b;
+  
+  gc_private = GDK_GC_FBDATA (gc);
+
+  fg = GDK_GC_FBDATA (gc)->values.foreground;
+  fg_r = fg.red >> 8;
+  fg_g = fg.green >> 8;
+  fg_b = fg.blue >> 8;
+  
+  for (y = start_y; y*draw_direction < end_y*draw_direction; y+=draw_direction)
+    {
+      for (x = start_x; x < end_x; x++)
+       {
+         grayval = smem[x + src_x_off + (y + src_y_off) * src_rowstride];
+
+         if ((grayval <= 2) && (!dc->draw_bg))
+           continue;
+
+         dst = &dmem[x*3 + y*dst_rowstride];
+         
+         if (grayval >= 254)
+           {
+             dst[gdk_display->red_byte] = fg_r;
+             dst[gdk_display->green_byte] = fg_g;
+             dst[gdk_display->blue_byte] = fg_b;
+           }
+         else if (grayval <= 2)
+           {
+             dst[gdk_display->red_byte] = GDK_GC_FBDATA (gc)->values.background.red >> 8;
+             dst[gdk_display->green_byte] = GDK_GC_FBDATA (gc)->values.background.green >> 8;
+             dst[gdk_display->blue_byte] = GDK_GC_FBDATA (gc)->values.background.blue >> 8;
+           }
+         else
+           {
+             r = dst[gdk_display->red_byte];
+             tmp = (fg_r - r) * (gint)grayval;
+             r = r + ((tmp + (tmp >> 8) + 0x80) >> 8);
+             dst[gdk_display->red_byte] = r;
+
+             g = dst[gdk_display->green_byte];
+             tmp = (fg_g - g) * (gint)grayval;
+             g = g + ((tmp + (tmp >> 8) + 0x80) >> 8);
+             dst[gdk_display->green_byte] = g;
+
+             b = dst[gdk_display->blue_byte];
+             tmp = (fg_b - b) * (gint)grayval;
+             b = b + ((tmp + (tmp >> 8) + 0x80) >> 8);
+             dst[gdk_display->blue_byte] = b;
+           }
+       }
+    }
+}
+
+/*************************************
+ * gc->fill_rectangle() implementations
+ *************************************/
+
+void
+gdk_fb_fill_rectangle_generic (GdkDrawable    *drawable,
+                              GdkGC          *gc,
+                              GdkRectangle   *rect,
+                              GdkColor       *color)
+{
+  GdkDrawableFBData *private;
+  GdkSpan *spans;
+  int i;
+
+  private = GDK_DRAWABLE_FBDATA (drawable);
+
+  spans = g_new (GdkSpan, rect->height);
+  for (i=0;i<rect->height;i++)
+    {
+      spans[i].x = rect->x - private->abs_x;
+      spans[i].y = rect->y+i - private->abs_y;
+      spans[i].width = rect->width;
+    }
+  gdk_fb_fill_spans (drawable, gc, spans, rect->height, TRUE);
+  g_free (spans);
+}
+
+void
+gdk_fb_fill_rectangle_simple_16 (GdkDrawable    *drawable,
+                                GdkGC          *gc,
+                                GdkRectangle   *rect,
+                                GdkColor       *color)
+{
+  GdkGCFBData *gc_private;
+  GdkDrawableFBData *private;
+  guchar *ptr;
+  guint rowstride;
+  int n;
+  gboolean extra;
+  int i;
+  guint32 pixel;
+  gint height;
+  
+  private = GDK_DRAWABLE_FBDATA (drawable);
+  gc_private = GDK_GC_FBDATA (gc);
+
+  rowstride = private->rowstride - rect->width*2;
+  ptr = (guchar *)private->mem + rect->y * private->rowstride + rect->x*2;
+
+  extra = rect->width&1;
+  n = rect->width>>1;
+    
+  pixel = (color->pixel << 16) | color->pixel;
+
+  height = rect->height;
+  while (height>0)
+    {
+      i = n;
+      while (i>0)
+       {
+         *(guint32 *)ptr = pixel;
+         ptr += 4;
+         i--;
+       }
+      if (extra)
+       {
+         *(guint16 *)ptr = color->pixel;
+         ptr += 2;
+       }
+      ptr += rowstride;
+      height--; 
+    }
+}
+
+void
+gdk_fb_fill_rectangle_simple_32 (GdkDrawable    *drawable,
+                                GdkGC          *gc,
+                                GdkRectangle   *rect,
+                                GdkColor       *color)
+{
+  GdkGCFBData *gc_private;
+  GdkDrawableFBData *private;
+  guchar *ptr;
+  guint rowstride;
+  int n;
+  int i;
+  guint32 pixel;
+  gint height;
+  
+  private = GDK_DRAWABLE_FBDATA (drawable);
+  gc_private = GDK_GC_FBDATA (gc);
+
+  rowstride = private->rowstride - rect->width*4;
+  ptr = (guchar *)private->mem + rect->y * private->rowstride + rect->x*4;
+
+  n = rect->width;
+    
+  pixel = color->pixel;
+
+  height = rect->height;
+  while (height>0)
+    {
+      i = n;
+      while (i>0)
+       {
+         *(guint32 *)ptr = pixel;
+         ptr += 4;
+         i--;
+       }
+      ptr += rowstride;
+      height--; 
+    }
+}
+
+
+/*************************************
+ * GC state calculation
+ *************************************/
+
+void
+_gdk_fb_gc_calc_state (GdkGC           *gc,
+                      GdkGCValuesMask  changed)
+{
+  GdkGCFBData *gc_private;
+  int i;
+
+  gc_private = GDK_GC_FBDATA (gc);
+
+  gc_private->fill_span = gdk_fb_fill_span_generic;
+  gc_private->fill_rectangle = gdk_fb_fill_rectangle_generic;
+
+  for (i=0;i<GDK_NUM_FB_SRCBPP;i++)
+    gc_private->draw_drawable[i] = gdk_fb_draw_drawable_generic;
+  
+  if (changed & _GDK_FB_GC_DEPTH)
+    switch (gc_private->depth)
+      {
+      case 1:
+       gc_private->set_pixel = gdk_fb_set_pixel_1;
+       gc_private->get_color = gdk_fb_get_color_1;
+       break;
+      case 8:
+       gc_private->set_pixel = gdk_fb_set_pixel_8;
+       gc_private->get_color = gdk_fb_get_color_8;
+       break;
+      case 16:
+       gc_private->set_pixel = gdk_fb_set_pixel_16;
+       gc_private->get_color = gdk_fb_get_color_16;
+       break;
+      case 24:
+       gc_private->set_pixel = gdk_fb_set_pixel_24;
+       gc_private->get_color = gdk_fb_get_color_24;
+       break;
+      case 32:
+       gc_private->set_pixel = gdk_fb_set_pixel_32;
+       gc_private->get_color = gdk_fb_get_color_32;
+       break;
+      default:
+       g_assert_not_reached ();
+       break;
+      }
+
+  if (!gc_private->values.clip_mask)
+    {
+    switch (gc_private->depth)
+      {
+      case 8:
+       gc_private->draw_drawable[GDK_FB_SRC_BPP_8] = gdk_fb_draw_drawable_memmove;
+       break;
+      case 16:
+       gc_private->draw_drawable[GDK_FB_SRC_BPP_16] = gdk_fb_draw_drawable_memmove;
+       break;
+      case 24:
+       gc_private->draw_drawable[GDK_FB_SRC_BPP_8_AA_GRAYVAL] = gdk_fb_draw_drawable_aa_24;
+       gc_private->draw_drawable[GDK_FB_SRC_BPP_24] = gdk_fb_draw_drawable_memmove;
+       break;
+      case 32:
+       gc_private->draw_drawable[GDK_FB_SRC_BPP_32] = gdk_fb_draw_drawable_memmove;
+       break;
+      }
+    }
+
+  if (!gc_private->values.clip_mask &&
+      !gc_private->values.tile &&
+      !gc_private->values.stipple &&
+       gc_private->values.function != GDK_INVERT)
+    {
+      switch (gc_private->depth)
+       {
+       case 1:
+         gc_private->fill_span = gdk_fb_fill_span_simple_1;
+         break;
+       case 8:
+         gc_private->fill_span = gdk_fb_fill_span_simple_8;
+         break;
+       case 16:
+         gc_private->fill_span = gdk_fb_fill_span_simple_16;
+         gc_private->fill_rectangle = gdk_fb_fill_rectangle_simple_16;
+         break;
+       case 24:
+         gc_private->fill_span = gdk_fb_fill_span_simple_24;
+         break;
+       case 32:
+         gc_private->fill_span = gdk_fb_fill_span_simple_32;
+         gc_private->fill_rectangle = gdk_fb_fill_rectangle_simple_32;
+         break;
+       default:
+         g_assert_not_reached ();
+         break;
+       }
+    }
+
+}
+
index 191ba81555036e1ac92044ffeff19f0402d4b36a..fecf5bb70994f5981f2d48c067b306ef1b8da789 100644 (file)
@@ -866,8 +866,8 @@ miComputeWideEllipse(int lw, miArc *parc, gboolean *mustFree)
 static void
 miFillWideEllipse(GdkDrawable *pDraw, GdkGC *pGC, miArc *parc)
 {
-    GdkRectangle* points;
-    register GdkRectangle* pts;
+    GdkSpan* points;
+    register GdkSpan* pts;
     miArcSpanData *spdata;
     gboolean mustFree;
     register miArcSpan *span;
@@ -875,7 +875,7 @@ miFillWideEllipse(GdkDrawable *pDraw, GdkGC *pGC, miArc *parc)
     register int n;
 
     yorgu = parc->height + GDK_GC_FBDATA(pGC)->values.line_width;
-    points = ALLOCATE_LOCAL(sizeof(GdkRectangle) * yorgu * 2);
+    points = ALLOCATE_LOCAL(sizeof(GdkSpan) * yorgu * 2);
     spdata = miComputeWideEllipse(GDK_GC_FBDATA(pGC)->values.line_width, parc, &mustFree);
     if (!spdata)
     {
@@ -893,7 +893,7 @@ miFillWideEllipse(GdkDrawable *pDraw, GdkGC *pGC, miArc *parc)
     {
        pts->x = xorg;
        pts->y = yorgu - 1;
-       pts->width = pts->height = 1;
+       pts->width = 1;
        pts++;
        span++;
     }
@@ -901,7 +901,6 @@ miFillWideEllipse(GdkDrawable *pDraw, GdkGC *pGC, miArc *parc)
     {
        pts[0].x = xorg + span->lx;
        pts[0].y = yorgu;
-       pts[0].height = 1;
        pts[0].width = span->lw;
        pts[1] = pts[0];
        pts[1].y = yorgl;
@@ -914,7 +913,7 @@ miFillWideEllipse(GdkDrawable *pDraw, GdkGC *pGC, miArc *parc)
     {
        pts[0].x = xorg;
        pts[0].y = yorgl;
-       pts[0].width = pts[0].height = 1;
+       pts[0].width = 1;
        pts++;
     }
     for (n = spdata->count2; --n >= 0; )
@@ -922,22 +921,18 @@ miFillWideEllipse(GdkDrawable *pDraw, GdkGC *pGC, miArc *parc)
        pts[0].x = xorg + span->lx;
        pts[0].y = yorgu;
        pts[0].width = span->lw;
-       pts[0].height = 1;
 
        pts[1].x = xorg + span->rx;
        pts[1].y = pts[0].y;
        pts[1].width = span->rw;
-       pts[1].height = 1;
 
        pts[2].x = pts[0].x;
        pts[2].y = yorgl;
-       pts[2].height = 1;
        pts[2].width = pts[0].width;
 
        pts[3].x = pts[1].x;
        pts[3].y = pts[2].y;
        pts[3].width = pts[1].width;
-       pts[3].height = 1;
 
        yorgu++;
        yorgl--;
@@ -951,7 +946,6 @@ miFillWideEllipse(GdkDrawable *pDraw, GdkGC *pGC, miArc *parc)
            pts[0].x = xorg + span->lx;
            pts[0].y = yorgu;
            pts[0].width = span->lw;
-           pts[0].height = 1;
            pts++;
        }
        else
@@ -959,18 +953,16 @@ miFillWideEllipse(GdkDrawable *pDraw, GdkGC *pGC, miArc *parc)
            pts[0].x = xorg + span->lx;
            pts[0].y = yorgu;
            pts[0].width = span->lw;
-           pts[0].height = 1;
            pts[1].x = xorg + span->rx;
            pts[1].y = pts[0].y;
            pts[1].width = span->rw;
-           pts[1].height = 1;
            pts += 2;
        }
     }
     if (mustFree)
        g_free(spdata);
 
-    gdk_fb_fill_spans(pDraw, pGC, points, pts - points);
+    gdk_fb_fill_spans(pDraw, pGC, points, pts - points, FALSE);
 
     DEALLOCATE_LOCAL(points);
 }
@@ -3039,15 +3031,15 @@ fillSpans (pDrawable, pGC)
     GdkGC*     pGC;
 {
        register struct finalSpan       *span;
-       register GdkRectangle*          xSpan;
+       register GdkSpan*               xSpan;
        register int                    i;
        register struct finalSpan       **f;
        register int                    spany;
-       GdkRectangle*                   xSpans;
+       GdkSpan*                        xSpans;
 
        if (nspans == 0)
                return;
-       xSpan = xSpans = (GdkRectangle*) ALLOCATE_LOCAL (nspans * sizeof (GdkRectangle));
+       xSpan = xSpans = (GdkSpan*) ALLOCATE_LOCAL (nspans * sizeof (GdkSpan));
        if (xSpans)
        {
            i = 0;
@@ -3059,13 +3051,12 @@ fillSpans (pDrawable, pGC)
                            xSpan->x = span->min;
                            xSpan->y = spany;
                            xSpan->width = span->max - span->min;
-                           xSpan->height = 1;
                            ++xSpan;
                            ++i;
                    }
            }
 
-           gdk_fb_fill_spans(pDrawable, pGC, xSpans, i);
+           gdk_fb_fill_spans(pDrawable, pGC, xSpans, i, TRUE);
        }
        disposeFinalSpans ();
        if (xSpans)
index 115be216c334ab06622d98c5fb9b9762d96d1bfe..31571c49943ca1e28b4a65cd3260fea238da36cb 100644 (file)
@@ -521,14 +521,12 @@ miFillArcSliceSetup(arc, slice, pGC)
     pts->x = xorg - x; \
     pts->y = yorg - y; \
     pts->width = slw; \
-    pts->height = 1; \
     pts++; \
     if (miFillArcLower(slw)) \
     { \
        pts->x = xorg - x; \
        pts->y = yorg + y + dy; \
         pts->width = slw; \
-        pts->height = 1; \
        pts++; \
     }
 
@@ -542,10 +540,10 @@ miFillEllipseI(pDraw, pGC, arc)
     int yk, xk, ym, xm, dx, dy, xorg, yorg;
     int slw;
     miFillArcRec info;
-    GdkRectangle* points;
-    register GdkRectangle* pts;
+    GdkSpan* points;
+    register GdkSpan* pts;
 
-    points = (GdkRectangle*)ALLOCATE_LOCAL(sizeof(GdkRectangle) * arc->height);
+    points = (GdkSpan*)ALLOCATE_LOCAL(sizeof(GdkSpan) * arc->height);
     if (!points)
        return;
     miFillArcSetup(arc, &info);
@@ -556,7 +554,7 @@ miFillEllipseI(pDraw, pGC, arc)
        MIFILLARCSTEP(slw);
        ADDSPANS();
     }
-    gdk_fb_fill_spans(pDraw, pGC, points, pts - points);
+    gdk_fb_fill_spans(pDraw, pGC, points, pts - points, FALSE);
 
     DEALLOCATE_LOCAL(points);
 }
@@ -571,10 +569,10 @@ miFillEllipseD(pDraw, pGC, arc)
     int xorg, yorg, dx, dy, slw;
     double e, yk, xk, ym, xm;
     miFillArcDRec info;
-    GdkRectangle* points;
-    register GdkRectangle* pts;
+    GdkSpan* points;
+    register GdkSpan* pts;
 
-    points = (GdkRectangle*)ALLOCATE_LOCAL(sizeof(GdkRectangle) * arc->height);
+    points = (GdkSpan*)ALLOCATE_LOCAL(sizeof(GdkSpan) * arc->height);
     if (!points)
        return;
     miFillArcDSetup(arc, &info);
@@ -585,7 +583,7 @@ miFillEllipseD(pDraw, pGC, arc)
        MIFILLARCSTEP(slw);
        ADDSPANS();
     }
-    gdk_fb_fill_spans(pDraw, pGC, points, pts - points);
+    gdk_fb_fill_spans(pDraw, pGC, points, pts - points, FALSE);
     DEALLOCATE_LOCAL(points);
 }
 
@@ -595,7 +593,6 @@ miFillEllipseD(pDraw, pGC, arc)
        pts->x = l; \
        pts->y = ya; \
         pts->width = r - l + 1; \
-        pts->height = 1; \
        pts++; \
     }
 
@@ -623,8 +620,8 @@ miFillArcSliceI(pDraw, pGC, arc)
     miFillArcRec info;
     miArcSliceRec slice;
     int ya, xl, xr, xc;
-    GdkRectangle* points;
-    register GdkRectangle* pts;
+    GdkSpan* points;
+    register GdkSpan* pts;
 
     miFillArcSetup(arc, &info);
     miFillArcSliceSetup(arc, &slice, pGC);
@@ -632,7 +629,7 @@ miFillArcSliceI(pDraw, pGC, arc)
     slw = arc->height;
     if (slice.flip_top || slice.flip_bot)
        slw += (arc->height >> 1) + 1;
-    points = (GdkRectangle*)ALLOCATE_LOCAL(sizeof(GdkRectangle) * slw);
+    points = (GdkSpan*)ALLOCATE_LOCAL(sizeof(GdkSpan) * slw);
     if (!points)
        return;
     pts = points;
@@ -655,7 +652,7 @@ miFillArcSliceI(pDraw, pGC, arc)
        }
     }
     
-    gdk_fb_fill_spans(pDraw, pGC, points, pts - points);
+    gdk_fb_fill_spans(pDraw, pGC, points, pts - points, FALSE);
     DEALLOCATE_LOCAL(points);
 }
 
@@ -671,8 +668,8 @@ miFillArcSliceD(pDraw, pGC, arc)
     miFillArcDRec info;
     miArcSliceRec slice;
     int ya, xl, xr, xc;
-    GdkRectangle* points;
-    register GdkRectangle* pts;
+    GdkSpan* points;
+    register GdkSpan* pts;
 
     miFillArcDSetup(arc, &info);
     miFillArcSliceSetup(arc, &slice, pGC);
@@ -680,7 +677,7 @@ miFillArcSliceD(pDraw, pGC, arc)
     slw = arc->height;
     if (slice.flip_top || slice.flip_bot)
        slw += (arc->height >> 1) + 1;
-    points = (GdkRectangle*)ALLOCATE_LOCAL(sizeof(GdkRectangle) * slw);
+    points = (GdkSpan*)ALLOCATE_LOCAL(sizeof(GdkSpan) * slw);
     if (!points)
        return;
     pts = points;
@@ -702,7 +699,7 @@ miFillArcSliceD(pDraw, pGC, arc)
            ADDSLICESPANS(slice.flip_bot);
        }
     }
-    gdk_fb_fill_spans(pDraw, pGC, points, pts - points);
+    gdk_fb_fill_spans(pDraw, pGC, points, pts - points, FALSE);
 
     DEALLOCATE_LOCAL(points);
 }
index 341512f3672372d1209100073d7795a84d8babd5..4b266b0dfbf42cd863147ccbcc9e85f023b4f49b 100644 (file)
@@ -93,7 +93,7 @@ miFillSppPoly(GdkDrawable *dst, GdkGC *pgc, int count, SppPointPtr ptsIn, int xT
     register int       left, right,    /* indices to first endpoints */
                        nextleft,
                        nextright;      /* indices to second endpoints */
-    GdkRectangle*      ptsOut,
+    GdkSpan*           ptsOut,
       *FirstPoint;     /* output buffer */
 
     imin = GetFPolyYBounds(ptsIn, count, yFtrans, &ymin, &ymax);
@@ -101,7 +101,7 @@ miFillSppPoly(GdkDrawable *dst, GdkGC *pgc, int count, SppPointPtr ptsIn, int xT
     y = ymax - ymin + 1;
     if ((count < 3) || (y <= 0))
        return;
-    ptsOut = FirstPoint = (GdkRectangle*)ALLOCATE_LOCAL(sizeof(GdkRectangle) * y);
+    ptsOut = FirstPoint = (GdkSpan*)ALLOCATE_LOCAL(sizeof(GdkSpan) * y);
     Marked = (int *) ALLOCATE_LOCAL(sizeof(int) * count);
 
     if(!ptsOut || !Marked)
@@ -198,7 +198,6 @@ miFillSppPoly(GdkDrawable *dst, GdkGC *pgc, int count, SppPointPtr ptsIn, int xT
 
            cxl = ICEIL(xl);
            cxr = ICEIL(xr);
-           ptsOut->height = 1;
             /* reverse the edges if necessary */
             if (xl < xr) 
             {
@@ -220,7 +219,7 @@ miFillSppPoly(GdkDrawable *dst, GdkGC *pgc, int count, SppPointPtr ptsIn, int xT
     }  while (y <= ymax);
 
     /* Finally, fill the spans we've collected */
-    gdk_fb_fill_spans(dst, pgc, FirstPoint, ptsOut-FirstPoint);
+    gdk_fb_fill_spans(dst, pgc, FirstPoint, ptsOut-FirstPoint, TRUE);
     DEALLOCATE_LOCAL(Marked);
     DEALLOCATE_LOCAL(FirstPoint);
 }
index 5068536c711c345f4da7ba69a7246d007fad6bac..6ad63c7a048fc1bd3c21e5c8172317990e58b918 100644 (file)
@@ -66,8 +66,8 @@ miFillGeneralPoly(dst, pgc, count, ptsIn)
     register int nPts = 0;          /* number of pts in buffer */
     register EdgeTableEntry *pWETE; /* Winding Edge Table      */
     register ScanLineList *pSLL;    /* Current ScanLineList    */
-    register GdkRectangle* ptsOut;      /* ptr to output buffers   */
-    GdkRectangle FirstPoint[NUMPTSTOBUFFER]; /* the output buffers */
+    register GdkSpan* ptsOut;      /* ptr to output buffers   */
+    GdkSpan FirstPoint[NUMPTSTOBUFFER]; /* the output buffers */
     EdgeTableEntry *pPrevAET;       /* previous AET entry      */
     EdgeTable ET;                   /* Edge Table header node  */
     EdgeTableEntry AET;             /* Active ET header node   */
@@ -115,7 +115,6 @@ miFillGeneralPoly(dst, pgc, count, ptsIn)
             {
                 ptsOut->x = pAET->bres.minor;
                ptsOut->width = pAET->next->bres.minor - pAET->bres.minor;
-               ptsOut->height = 1;
                ptsOut++->y = y;
                 nPts++;
 
@@ -124,7 +123,7 @@ miFillGeneralPoly(dst, pgc, count, ptsIn)
                  */
                 if (nPts == NUMPTSTOBUFFER) 
                {
-                 gdk_fb_fill_spans(dst, pgc, FirstPoint, nPts);
+                 gdk_fb_fill_spans(dst, pgc, FirstPoint, nPts, TRUE);
                  ptsOut = FirstPoint;
                  nPts = 0;
                 }
@@ -169,7 +168,6 @@ miFillGeneralPoly(dst, pgc, count, ptsIn)
                 {
                     ptsOut->x = pAET->bres.minor;
                    ptsOut->width = pAET->nextWETE->bres.minor - pAET->bres.minor;
-                   ptsOut->height = 1;
                    ptsOut++->y = y;
                     nPts++;
 
@@ -178,7 +176,7 @@ miFillGeneralPoly(dst, pgc, count, ptsIn)
                      */
                     if (nPts == NUMPTSTOBUFFER) 
                     {
-                     gdk_fb_fill_spans(dst, pgc, FirstPoint, nPts);
+                     gdk_fb_fill_spans(dst, pgc, FirstPoint, nPts, TRUE);
                      ptsOut = FirstPoint;
                      nPts = 0;
                     }
@@ -207,7 +205,7 @@ miFillGeneralPoly(dst, pgc, count, ptsIn)
      *     Get any spans that we missed by buffering
      */
     if(nPts > 0)
-      gdk_fb_fill_spans(dst, pgc, FirstPoint, nPts);
+      gdk_fb_fill_spans(dst, pgc, FirstPoint, nPts, TRUE);
     DEALLOCATE_LOCAL(pETEs);
     miFreeStorage(SLLBlock.next);
     return(TRUE);
index a8638dd858ca8a1bb655d3fb0ad2d5997fc00528..4e2be42ab7d9a0a66df127c7c21b77fd9ca4e6f1 100644 (file)
@@ -78,7 +78,7 @@ void miSubtractSpans (spanGroup, sub)
     int                i, subCount, spansCount;
     int                ymin, ymax, xmin, xmax;
     Spans      *spans;
-    GdkRectangle*      subPt, *spansPt;
+    GdkSpan*   subPt, *spansPt;
     int                extra;
 
     ymin = YMIN(sub);
@@ -137,10 +137,10 @@ void miSubtractSpans (spanGroup, sub)
                        else
                        {
                            if (!extra) {
-                               GdkRectangle* newPt;
+                               GdkSpan* newPt;
 
 #define EXTRA 8
-                               newPt = (GdkRectangle*) g_realloc (spans->points, (spans->count + EXTRA) * sizeof (GdkRectangle));
+                               newPt = (GdkSpan*) g_realloc (spans->points, (spans->count + EXTRA) * sizeof (GdkSpan));
                                if (!newPt)
                                    break;
                                spansPt = newPt + (spansPt - spans->points);
@@ -151,10 +151,8 @@ void miSubtractSpans (spanGroup, sub)
                            spans->count++;
                            extra--;
                            spansPt->width = xmin - spansPt->x;
-                           spansPt->height = 1;
                            spansPt++;
                            spansPt->width -= xmax - spansPt->x;
-                           spansPt->height = 1;
                            spansPt->x = xmax;
                        }
                    }
@@ -207,19 +205,19 @@ void miFreeSpanGroup(spanGroup)
 }
 
 static void QuickSortSpansX(points, numSpans)
-    register GdkRectangle    points[];
+    register GdkSpan        points[];
     register int           numSpans;
 {
     register int           x;
     register int           i, j, m;
-    register GdkRectangle*    r;
+    register GdkSpan*    r;
 
 /* Always called with numSpans > 1 */
 /* Sorts only by x, as all y should be the same */
 
 #define ExchangeSpans(a, b)                                \
 {                                                          \
-    GdkRectangle     tpt;                                  \
+    GdkSpan     tpt;                               \
                                                            \
     tpt = points[a]; points[a] = points[b]; points[b] = tpt;    \
 }
@@ -235,7 +233,7 @@ static void QuickSortSpansX(points, numSpans)
                x = points[i].x;
                if (xprev > x) {
                    /* points[i] is out of order.  Move into proper location. */
-                   GdkRectangle tpt;
+                   GdkSpan tpt;
                    int     k;
 
                    for (j = 0; x >= points[j].x; j++) {}
@@ -289,10 +287,10 @@ static void QuickSortSpansX(points, numSpans)
 
 static int UniquifySpansX(spans, newPoints, newWidths)
     Spans                  *spans;
-    register GdkRectangle    *newPoints;
+    register GdkSpan    *newPoints;
 {
     register int newx1, newx2, oldpt, i, y;
-    GdkRectangle    *oldPoints, *startNewPoints = newPoints;
+    GdkSpan    *oldPoints, *startNewPoints = newPoints;
 
 /* Always called with numSpans > 1 */
 /* Uniquify the spans, and stash them into newPoints and newWidths.  Return the
@@ -313,7 +311,6 @@ static int UniquifySpansX(spans, newPoints, newWidths)
            newPoints->x = newx1;
            newPoints->y = y;
            newPoints->width = newx2 - newx1;
-           newPoints->height = 1;
            newPoints++;
            newx1 = oldpt;
            newx2 = oldpt + oldPoints->width;
@@ -327,7 +324,6 @@ static int UniquifySpansX(spans, newPoints, newWidths)
     /* Write final span */
     newPoints->x = newx1;
     newPoints->width = newx2 - newx1;
-    newPoints->height = 1;
     newPoints->y = y;
 
     return (newPoints - startNewPoints) + 1;
@@ -359,7 +355,7 @@ void miFillUniqueSpanGroup(pDraw, pGC, spanGroup)
     register int    ymin, ylength;
 
     /* Outgoing spans for one big call to FillSpans */
-    register GdkRectangle*    points;
+    register GdkSpan*    points;
     register int           count;
 
     if (spanGroup->count == 0) return;
@@ -367,7 +363,7 @@ void miFillUniqueSpanGroup(pDraw, pGC, spanGroup)
     if (spanGroup->count == 1) {
        /* Already should be sorted, unique */
        spans = spanGroup->group;
-       gdk_fb_fill_spans(pDraw, pGC, spans->points, spans->count);
+       gdk_fb_fill_spans(pDraw, pGC, spans->points, spans->count, TRUE);
        g_free(spans->points);
     }
     else
@@ -415,11 +411,11 @@ void miFillUniqueSpanGroup(pDraw, pGC, spanGroup)
                if (index >= 0 && index < ylength) {
                    Spans *newspans = &(yspans[index]);
                    if (newspans->count == ysizes[index]) {
-                       GdkRectangle* newpoints;
+                       GdkSpan* newpoints;
                        ysizes[index] = (ysizes[index] + 8) * 2;
-                       newpoints = (GdkRectangle*) g_realloc(
+                       newpoints = (GdkSpan*) g_realloc(
                            newspans->points,
-                           ysizes[index] * sizeof(GdkRectangle));
+                           ysizes[index] * sizeof(GdkSpan));
                        if (!newpoints)
                        {
                            int i;
@@ -445,7 +441,7 @@ void miFillUniqueSpanGroup(pDraw, pGC, spanGroup)
        } /* for i thorough Spans */
 
        /* Now sort by x and uniquify each bucket into the final array */
-       points = (GdkRectangle*) g_malloc(count * sizeof(GdkRectangle));
+       points = (GdkSpan*) g_malloc(count * sizeof(GdkSpan));
        if (!points)
        {
            int i;
@@ -476,7 +472,7 @@ void miFillUniqueSpanGroup(pDraw, pGC, spanGroup)
            }
        }
 
-       gdk_fb_fill_spans(pDraw, pGC, points, count);
+       gdk_fb_fill_spans(pDraw, pGC, points, count, TRUE);
        g_free(points);
        g_free(yspans);
        g_free(ysizes);         /* use (DE)ALLOCATE_LOCAL for these? */
@@ -497,7 +493,7 @@ void miFillSpanGroup(pDraw, pGC, spanGroup)
     register Spans  *spans;
 
     for (i = 0, spans = spanGroup->group; i != spanGroup->count; i++, spans++) {
-      gdk_fb_fill_spans(pDraw, pGC, spans->points, spans->count);
+      gdk_fb_fill_spans(pDraw, pGC, spans->points, spans->count, TRUE);
       g_free(spans->points);
     }
 
index 4724e203edc70840efe67d29b458d83dfe34c610..a620b938dc4c4030f44ac5fe3f1e26f4ddb64d8f 100644 (file)
@@ -45,7 +45,7 @@ SOFTWARE.
 
 typedef struct {
     int         count;         /* number of spans                  */
-    GdkRectangle* points;              /* pointer to list of start points  */
+    GdkSpan* points;           /* pointer to list of start points  */
 } Spans;
 
 typedef struct {
index e7b6b8329098276040eb89d56ea6725666bfa67b..79b7597702b4db2c12309ba82257ba2c9f204a29 100644 (file)
@@ -80,8 +80,8 @@ miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, overall_height,
     int        height = 0;
     int        left_height = 0, right_height = 0;
 
-    register GdkRectangle* ppt;
-    GdkRectangle* pptInit;
+    register GdkSpan* ppt;
+    GdkSpan* pptInit;
     GdkColor           oldPixel;
     int                xorg;
     Spans      spanRec;
@@ -91,7 +91,7 @@ miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, overall_height,
     
     if (!spanData)
     {
-       pptInit = (GdkRectangle*) ALLOCATE_LOCAL (overall_height * sizeof(*ppt));
+       pptInit = (GdkSpan*) ALLOCATE_LOCAL (overall_height * sizeof(*ppt));
        if (!pptInit)
            return;
        ppt = pptInit;
@@ -103,7 +103,7 @@ miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, overall_height,
     }
     else
     {
-       spanRec.points = (GdkRectangle*) g_malloc (overall_height * sizeof (*ppt));
+       spanRec.points = (GdkSpan*) g_malloc (overall_height * sizeof (*ppt));
        if (!spanRec.points)
            return;
        ppt = spanRec.points;
@@ -130,7 +130,6 @@ miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, overall_height,
                ppt->y = y;
                ppt->x = left_x + xorg;
                ppt->width = right_x - left_x + 1;
-               ppt->height = 1;
                ppt++;
            }
            y++;
@@ -142,7 +141,7 @@ miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, overall_height,
     }
     if (!spanData)
     {
-      gdk_fb_fill_spans(pDrawable, pGC, pptInit, ppt - pptInit);
+      gdk_fb_fill_spans(pDrawable, pGC, pptInit, ppt - pptInit, TRUE);
       DEALLOCATE_LOCAL (pptInit);
       if (pixel->pixel != oldPixel.pixel)
        {
@@ -164,23 +163,18 @@ miFillRectPolyHelper (pDrawable, pGC, pixel, spanData, x, y, w, h)
     SpanDataPtr        spanData;
     int                x, y, w, h;
 {
-    register GdkRectangle* ppt;
-    GdkColor           oldPixel;
+    register GdkSpan* ppt;
+    GdkColor   oldPixel;
     Spans      spanRec;
-    GdkRectangle  rect;
 
     if (!spanData)
     {
-       rect.x = x;
-       rect.y = y;
-       rect.width = w;
-       rect.height = h;
        oldPixel = GDK_GC_FBDATA(pGC)->values.foreground;
        if (pixel->pixel != oldPixel.pixel)
        {
          gdk_gc_set_foreground(pGC, pixel);
        }
-       gdk_fb_fill_spans(pDrawable, pGC, &rect, 1);
+        gdk_fb_draw_rectangle(pDrawable, pGC, TRUE, x, y, w, h);
        if (pixel->pixel != oldPixel.pixel)
        {
          gdk_gc_set_foreground(pGC, &oldPixel);
@@ -188,7 +182,7 @@ miFillRectPolyHelper (pDrawable, pGC, pixel, spanData, x, y, w, h)
     }
     else
     {
-       spanRec.points = (GdkRectangle*) g_malloc (h * sizeof (*ppt));
+       spanRec.points = (GdkSpan*) g_malloc (h * sizeof (*ppt));
        if (!spanRec.points)
            return;
        ppt = spanRec.points;
@@ -198,7 +192,6 @@ miFillRectPolyHelper (pDrawable, pGC, pixel, spanData, x, y, w, h)
            ppt->x = x;
            ppt->y = y;
            ppt->width = w;
-           ppt->height = 1;
            ppt++;
            y++;
        }
@@ -384,14 +377,15 @@ miLineOnePoint (pDrawable, pGC, pixel, spanData, x, y)
     SpanDataPtr            spanData;
     int                    x, y;
 {
-    GdkColor   oldPixel;
-    GdkRectangle rect;
+    GdkColor oldPixel;
+    GdkSpan  span;
 
     MILINESETPIXEL (pDrawable, pGC, pixel, oldPixel);
-    rect.width = 1;
-    rect.height = 1;
+    span.x = x;
+    span.y = y;
+    span.width = 1;
 
-    gdk_fb_fill_spans(pDrawable, pGC, &rect, 1);
+    gdk_fb_fill_spans(pDrawable, pGC, &span, 1, TRUE);
     MILINERESETPIXEL (pDrawable, pGC, pixel, oldPixel);
 }
 
@@ -542,9 +536,9 @@ miLineArcI (pDraw, pGC, xorg, yorg, points, widths)
     GdkDrawable*           pDraw;
     GdkGC*         pGC;
     int                    xorg, yorg;
-    GdkRectangle*          points;
+    GdkSpan*       points;
 {
-    register GdkRectangle* tpts, *bpts;
+    register GdkSpan* tpts, *bpts;
     register int x, y, e, ex, slw;
 
     tpts = points;
@@ -554,7 +548,6 @@ miLineArcI (pDraw, pGC, xorg, yorg, points, widths)
        tpts->x = xorg;
        tpts->y = yorg;
        tpts->width = 1;
-       tpts->height = 1;
        return 1;
     }
     bpts = tpts + slw;
@@ -580,14 +573,12 @@ miLineArcI (pDraw, pGC, xorg, yorg, points, widths)
        tpts->x = xorg - x;
        tpts->y = yorg - y;
        tpts->width = slw;
-       tpts->height = 1;
        tpts++;
        if ((y != 0) && ((slw > 1) || (e != ex)))
        {
            bpts--;
            bpts->x = xorg - x;
            bpts->y = yorg + y;
-           bpts->height = 1;
            bpts->width = slw;
        }
     }
@@ -623,12 +614,12 @@ miLineArcD (pDraw, pGC, xorg, yorg, points, widths,
     GdkDrawable*           pDraw;
     GdkGC*         pGC;
     double         xorg, yorg;
-    GdkRectangle*   points;
+    GdkSpan*        points;
     PolyEdgePtr            edge1, edge2;
     int                    edgey1, edgey2;
     gboolean       edgeleft1, edgeleft2;
 {
-    register GdkRectangle* pts;
+    register GdkSpan* pts;
     double radius, x0, y0, el, er, yk, xlk, xrk, k;
     int xbase, ybase, y, boty, xl, xr, xcl, xcr;
     int ymin, ymax;
@@ -731,7 +722,6 @@ miLineArcD (pDraw, pGC, xorg, yorg, points, widths,
            pts->x = xcl;
            pts->y = ybase;
            pts->width = xcr - xcl + 1;
-           pts->height = 1;
            pts++;
        }
     }
@@ -768,7 +758,6 @@ miLineArcD (pDraw, pGC, xorg, yorg, points, widths,
            pts->x = xcl;
            pts->y = ybase;
            pts->width = xcr - xcl + 1;
-           pts->height = 1;
            pts++;
        }
     }
@@ -909,7 +898,7 @@ miLineArc (pDraw, pGC, pixel, spanData, leftFace, rightFace, xorg, yorg, isInt)
     double         xorg, yorg;
     gboolean       isInt;
 {
-    GdkRectangle* points;
+    GdkSpan* points;
     int xorgi = 0, yorgi = 0;
     GdkColor           oldPixel;
     Spans spanRec;
@@ -957,7 +946,7 @@ miLineArc (pDraw, pGC, pixel, spanData, leftFace, rightFace, xorg, yorg, isInt)
     }
     if (!spanData)
     {
-       points = (GdkRectangle*)ALLOCATE_LOCAL(sizeof(GdkRectangle) * GDK_GC_FBDATA(pGC)->values.line_width);
+       points = (GdkSpan*)ALLOCATE_LOCAL(sizeof(GdkSpan) * GDK_GC_FBDATA(pGC)->values.line_width);
        if (!points)
            return;
        oldPixel = GDK_GC_FBDATA(pGC)->values.foreground;
@@ -968,7 +957,7 @@ miLineArc (pDraw, pGC, pixel, spanData, leftFace, rightFace, xorg, yorg, isInt)
     }
     else
     {
-       points = (GdkRectangle*) g_malloc (GDK_GC_FBDATA(pGC)->values.line_width * sizeof (GdkRectangle));
+       points = (GdkSpan*) g_malloc (GDK_GC_FBDATA(pGC)->values.line_width * sizeof (GdkSpan));
        if (!points)
            return;
        spanRec.points = points;
@@ -982,7 +971,7 @@ miLineArc (pDraw, pGC, pixel, spanData, leftFace, rightFace, xorg, yorg, isInt)
 
     if (!spanData)
     {
-      gdk_fb_fill_spans(pDraw, pGC, points, n);
+      gdk_fb_fill_spans(pDraw, pGC, points, n, TRUE);
       DEALLOCATE_LOCAL(points);
       if (pixel->pixel != oldPixel.pixel)
        {
index 8b82a219eee9ba13e71b0656b5fcdea63fc8168d..4c2adf040b115952439104289f80fa3ffb650363 100644 (file)
@@ -79,7 +79,6 @@ SOFTWARE.
        spans->x = xx;\
        spans->y = yy;\
         spans->width = 1; \
-        spans->height = 1; \
        current_y = yy;\
         new_span = FALSE;\
     }\
@@ -95,7 +94,7 @@ miZeroLine(pDraw, pGC, mode, npt, pptInit)
 {
     int Nspans, current_y;
     GdkPoint* ppt; 
-    GdkRectangle* pspanInit, *spans;
+    GdkSpan* pspanInit, *spans;
     int list_len;
     int xleft, ytop, xright, ybottom;
     int new_x1, new_y1, new_x2, new_y2;
@@ -130,7 +129,7 @@ miZeroLine(pDraw, pGC, mode, npt, pptInit)
     width = xright - xleft + 1;
     height = ybottom - ytop + 1;
     list_len = (height >= width) ? height : width;
-    pspanInit = (GdkRectangle*)ALLOCATE_LOCAL(list_len * sizeof(GdkRectangle));
+    pspanInit = (GdkSpan*)ALLOCATE_LOCAL(list_len * sizeof(GdkSpan));
     if (!pspanInit)
        return;
 
@@ -153,7 +152,7 @@ miZeroLine(pDraw, pGC, mode, npt, pptInit)
     while (--npt > 0)
     {
        if (Nspans > 0)
-         gdk_fb_fill_spans(pDraw, pGC, pspanInit, Nspans);
+         gdk_fb_fill_spans(pDraw, pGC, pspanInit, Nspans, FALSE);
        Nspans = 0;
        new_span = TRUE;
        spans  = pspanInit - 1;
@@ -312,7 +311,7 @@ miZeroLine(pDraw, pGC, mode, npt, pptInit)
     }    
 
     if (Nspans > 0)
-      gdk_fb_fill_spans(pDraw, pGC, pspanInit, Nspans);
+      gdk_fb_fill_spans(pDraw, pGC, pspanInit, Nspans, FALSE);
 
     DEALLOCATE_LOCAL(pspanInit);
 }